I'm pretty new to graphql and apollo, and I'm working on a project where I need to be able to use context
to get a variable for my query. The issue that I'm having is that my context.user
is coming back null because my req.headers.authorization
is undefined. I'm unsure as to why this is happening as in my frontend
const authLink = setContext(async (_, { headers }) => {
const token = await AsyncStorage.getItem('token');
try {
if (token !== null) {
return {
headers: {
...headers,
authorization: `Bearer ${token}` || null,
}
}
}
}
catch (error) {
throw error;
}
});
my token is not null and when I tested const auth: `Bearer ${token}` || null console.log(auth)
after if (token !== null) {
it came back with Bearer and my token value. Does anyone know why this is happening? I would really appreciate any help or advice. Thank you!
rest of frontend client.js
import { ApolloClient, split, createHttpLink, HttpLink, InMemoryCache } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
import { setContext } from "@apollo/client/link/context";
import AsyncStorage from '@react-native-async-storage/async-storage';
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { createClient } from "graphql-ws";
const wslink = new GraphQLWsLink(
createClient({
url: "ws://localhost:4000/subscriptions",
/* connectionParams: {
authToken: user.authToken,
},*/
}),
);
const httpLink = new HttpLink({
uri: 'http://localhost:4000/graphql',
});
const authLink = setContext(async (_, { headers }) => {
const token = await AsyncStorage.getItem('token');
try {
if (token !== null) {
return {
headers: {
...headers,
authorization: `Bearer ${token}` || null,
}
}
}
}
catch (error) {
throw error;
}
});
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wslink,
authLink.concat(httpLink)
);
export const client = new ApolloClient({
link: splitLink,
cache: new InMemoryCache(),
});
backend index.js
import express from 'express';
import mongoose from 'mongoose';
import WebSocket from 'ws';
import { createServer } from 'http';
import { ApolloServer } from 'apollo-server-express';
import { makeExecutableSchema } from '@graphql-tools/schema';
import {
ApolloServerPluginDrainHttpServer,
ApolloServerPluginLandingPageLocalDefault,
} from "apollo-server-core";
import { useServer } from 'graphql-ws/lib/use/ws';
import constants from './config/constants.js';
import typeDefs from './graphql/schema.js';
import resolvers from './graphql/resolvers/index.js';
import { decodeToken } from './services/auth.js';
const app = express();
const httpServer = createServer(app);
const schema = makeExecutableSchema({ typeDefs, resolvers });
const server = new ApolloServer({
schema,
context: ({ req }) => ({
user: req.user
}),
csrfPrevention: true,
cache: "bounded",
plugins: [
ApolloServerPluginDrainHttpServer({ httpServer }),
{
async serverWillStart() {
return {
async drainServer() {
await serverCleanup.dispose();
},
};
},
},
ApolloServerPluginLandingPageLocalDefault({ embed: true }),
],
});
const wsServer = new WebSocket.Server({
server: httpServer,
path: '/graphql',
});
const serverCleanup = useServer({ schema }, wsServer);
async function auth(req, res, next) {
try {
const token = req.headers.authorization;
//token is undefined Why???
if (token != null) {
const user = await decodeToken(token);
req.user = user; // eslint-disable-line
}
else {
req.user = null; // eslint-disable-line
}
next();
} catch (error) {
throw error;
}
}
app.use(auth);
await server.start();
server.applyMiddleware({ app });
mongoose
.connect(process.env.MONGODB_URL || 'mongodb://localhost/AMO', {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log("MongoDB Connected");
return httpServer.listen(4000, () => {
console.log(`Server ready at http://localhost:4000/graphql`);
});
})