Closed HBCharles closed 6 years ago
It looks like you are not calling the passport.authenticate()
middleware in your /graphql route
Could you show me where to add the middleware ? Do I need to modify the applyMiddleware function ?
You just need to call passport middleware before server.applyMiddleware.
app.post('/login',
passport.authenticate('local', { session: true }),
function(req, res) {
// req.user defined
console.log('in login:', req.user)
res.redirect('/ok');
}
);
app.get('/ok',
function(req, res) {
// req.user defined
console.log('in ok:', req.user)
res.json(req.user)
}
);
// default endpoint path is /graphql
app.use('/graphql', passport.authenticate('local', { session: true }));
server.applyMiddleware({ app });
app.listen({ port: 3000 }, () =>
console.log(`🚀 Server ready at http://localhost:3000${server.graphqlPath}`)
)
It looks like the graphql server is not running anymore when I add the middleware. I got a 400 error code.
@HBCharles did you solve this?
Faced similar problem, but in the end the issue was my lack of understand on how passportjs lib works.
Had to customize passport.authenticate
callback function to bypass the authentication error and manually set the req.user
value
I don't understand the significance of this line:
app.use('/graphql', passport.authenticate('local', { session: true }));
No examples I have seen explicitly add any passport auth middlewares to the /graphql
endpoint. Also what if you have many passport providers, like Steam and Google? Do you need to add all of them as middleware to the /graphql
endpoint?
This might be what is causing the issue I just posted (#1657), but I'm confused because I have never seen examples (neither official nor unofficial) that explicitly mount middleware over gql.
Furthermore, if I add a middleware on /graphql
like you suggest @tux-tn, it sends me to auth with the provider (Steam in the case I tested), which sends me back to my loginUrl, and then when I go back to /graphql
it does the same thing. Over and over. So I don't see how mounting middleware like that is supposed to help.
If you testing on playground, u need aded playground: { settings: { 'request.credentials': 'include', }, },
in ApolloServer
options. Example use passport-local & graphQL you can see here https://github.com/bakhaa/react-express/blob/master/api/resolvers/user.js
On the extension from @bakhaa 's solution, if you are using apollo-link-http
in frontend, you should add credentials
option with 'include'
to attach your session cookie on your request to GraphQL server, otherwise there will be nothing with passport
on req.session
, including req.user
.
const httpLink = createHttpLink({
uri: `${API_URL}/graphql`,
credentials: 'include'
})
please improve documentation for passport / oauth / session with context in apollo server
I am having the same issue...
This is my GraphQL local strategy
passport.use(
new GraphQLLocalStrategy((email, password, next) => {
console.log(`🎫 ${JSON.stringify(User)} 🚔 👮♂`)
User.findOne({ email })
.then(user => !user
? next(null, false, 'Invalid email or password')
: user.checkPassword(password) //bcrypt
.then(match => !match
? next(null, false, 'Invalid email or password')
: next(null, user)
)
)
.catch(error => next(error))
}),
);
and the apolloServer configuration:
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req, res }) => buildContext({ req, res, User }),
playground: {
settings: {
'request.credentials': 'same-origin',
},
},
})
Where do I have to apply the passport.authenticate(?) @tux-tn Did you find a solution @HBCharles
I'm trying to access user in Apollo Server 2 context but got undefined. The req.user is correctly defined in the express middleware.
You can find a minimal reproduction here
server.js
passport.js