Reputation: 19
i pass currentuser auth to app middlware and it works just fine... but when i run subscription in graphql its saying current user not found.... what i am doing wrong guys ? when i remove just currentuser from apollo server it works...i was trying to follow docs from apollo website to create this
ive tried move logic to the body of apollo server but it didnt work out for some reason
const express = require('express');
const mongoose = require('mongoose');
const jwt = require('jsonwebtoken');
const cors = require('cors');
require('dotenv').config({ path: 'variables.env' });
const app = express();
const { createServer } = require('http');
const corsOptions = {
origin:'http://localhost:8000',
credentials:true
};
mongoose.set('useFindAndModify', false);
app.use(cors(corsOptions));
app.use(async (req , res , next) => {
const token = req.headers["authorization"];
if(token !== "null"){
try{
const currentUser = await jwt.verify(token, process.env.SECRET);
req.currentUser = currentUser;
console.log(currentUser)
}catch(err){
console.log(err)
}
}
next();
})
const Event = require('./models/Event');
const User = require('./models/User');
const Message = require('./models/Messages');
const { ApolloServer } = require('apollo-server-express');
const { typeDefs } = require('./Schema');
const { resolvers } = require('./Resolvers');
mongoose
.connect(process.env.MONGO_URI, {useNewUrlParser: true , useCreateIndex: true})
.then(() => console.log('DB connected'))
.catch(err => console.error(err))
const SERVER = new ApolloServer({
typeDefs,
resolvers,
context: ({req, res}) => ({
Event,
User,
Message,
currentUser:req.currentUser
}),
playground: {
settings: {
'editor.theme': 'dark'
}
}
});
SERVER.applyMiddleware({ app , path:'/graphql' });
const httpServer = createServer(app);
SERVER.installSubscriptionHandlers(httpServer);
const PORT = process.env.PORT || 5000;
httpServer.listen({ port: PORT }, () =>{
console.log(`🚀 Server ready at http://localhost:${PORT}${SERVER.graphqlPath}`)
console.log(`🚀 Subscriptions ready at ws://localhost:${PORT}${SERVER.subscriptionsPath}`)
})
Upvotes: 0
Views: 455
Reputation: 9979
In the case of subscriptions, you're using web sockets instead of regular http requests, so your token is available elsewhere, namely under connection.context.Authorization
(note the uppercase 'A'), connection
being provided by the function attached to the context
of your ApolloServer and being defined in the context of subscriptions.
You basically will want to move token verification to your ApolloServer declaration:
const SERVER = new ApolloServer({
typeDefs,
resolvers,
context: ({req, connection}) => ({
Event,
User,
Message,
currentUser: async () => {
const token = connection
? connection.context.Authorization
: req.headers.authorization
return await jwt.verify(token, process.env.SECRET)
},
}),
...
This is a really bare bones example, you could check for the existence of req
as well and generate an error if neither connection
nor req
are set, handle the case where there is no token, etc., but you get the basic idea.
See Context with Subscriptions in the Apollo Server docs for further reference.
Upvotes: 1