Passport.serialize is getting the user, but ctx.isAuthenticated() always returns false
jenkynolasco11 opened this issue · 8 comments
Here is my code:
// passport-init.js
import passport from 'koa-passport'
import { Strategy } from 'passport-local'
import {
User,
isValidPass,
createHash
} from './UserSchema'
passport.serializeUser( (user, done) => {
console.log(user) // it returns the user
done(null, user._id)
})
passport.deserializeUser( (id, done) => User.findById(id, done) )
// local login
passport.use(new Strategy(async (username, password, done) => {
//
let user = null
try{
user = await User.findOne({ username })
if(!user || await !isValidPass(user.password, password)) user = null
//
} catch(e) {
//
console.log('Something happened while logging in: ', e)
}
// I always get the user
return done(null,
user
? user
: false)
}))
// Signup
passport.use('signup', new Strategy({
passReqToCallback : true,
//
}, async (req, username, pass, done) => {
let user = null
let password = null
let { email } = req.body
try {
user = await User.findOne({ username })
email = await User.findOne({ email })
password = await createHash(pass)
// if error, then it means username/email already exists
if(user || email) return done(null, false)
user = await new User({
username,
email,
password
}).save()
//
} catch (e) {
//
console.log('Something happened while signing up: ', e)
}
// I always get the user
return done(null,
user
? user
: false)
}))
And this is my authentication router
// auth.js
// ...
const routes = () => {
const route = new Router()
route.prefix('/auth')
route.get('/login', ctx => {
ctx.state = { title : 'Login', login : true, csrf: ctx.csrf }
ctx.render('login')
})
route.get('/signup', ctx => {
ctx.state = { title : 'Signup', signup : true, csrf: ctx.csrf }
ctx.render('login')
})
// TODO: fix this later
route.post('/login', passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/auth/login',
}))
// TODO: fix this later
route.post('/signup', passport.authenticate('signup', {
successRedirect: '/',
failureRedirect: '/auth/signup',
}))
route.get('/logout', async ctx => {
await ctx.logout()
ctx.redirect('/')
})
return route
}
// index.js
const isAuthenticated = (ctx, next) => {
console.log(ctx.isAuthenticated()) // always returns false
console.log(ctx.state) // gives me the state, but never gives me the user back
if(ctx.isAuthenticated())
return next() // this never gets called
return ctx.redirect('/auth/login') // it always redirects me to login page
}
indexRoute.get('/', isAuthenticated, async (ctx, next) => {
ctx.status = 200
ctx.state = { title : 'Index', user : ctx.state.user }
await ctx.render('index')
})
After transversing through the /auth/login
route and entering the user and password properly, passport bounces me out, saying that I'm not authenticated, returning false when I call ctx.isAuthenticated()
.
Anything I might be missing?
Wasn't able to spot an error, yet, so I can only guess.
Does User.findById(id, done)
in passport.deserializeUser( (id, done) => User.findById(id, done) )
really calls the callback with a user?
@rkusa the done callback was being executed with a user, but after thoroughly searching inside the module, it seemed that passport
heavily depends on a session module, which I didn't have working properly at the time. After fixing the session module, this started to work "magically". I can't recall having this experience using express since the session module wasn't dependent on the express version, like in Koa. I had to check various modules to look which one would work properly, even tho the koa-session2
was supposed to work with Koa version 2, but it didn't.
Well, I'm closing this issue since I solved my problem. Thanks for replying 💯
@jenkynolasco11 Which session module did you end up using? I'm running into a similar situation using koa-session.
The same problem. Please tell me how did u solved the problem and what did u fix into the session module exactly.
I just used koa-session and it seems to work for me. Here's my packages and I'm on node 8.1.3
"koa": "^2.3.0",
"koa-bodyparser": "^4.2.0",
"koa-passport": "^3.0.0",
"koa-router": "^7.2.1",
"koa-session": "^5.4.0",
@mrchief I am using the same packages but I am not sure if I am configuring koa-session correctly. Can you provide me with your configuration for koa-session or you are using the default configuration?
@tpopov94 Just the default setup:
app.use(session(
{
key: 'myapp',
maxAge: 'session'
},
app
))
@cpurtlebaugh & @TotallWAR :
I had a similar issue where isAuthenticated() never returned true and after a short debugging reason was found from session configuration. I was missing keys parameter for session encryption. So to configure session correctly I did following :
const CONFIG = {
key:'koa:sess',
maxAge: 10000
};
// sessions
app.keys = ['super-secret-key']; // <--- I was missing this one.
app.use(session(CONFIG, app));
There was a pretty clear debug message saying about the case.