使用护照和护照。validationAFTER路线申报

我正在处理的应用程序要求所有的validation代码都放在路由声明之后,而不是通过中间件将路由分隔到公共和私有路由中,并且调用passport.authenticate在login方法(代码A)的callback中,我需要加载所有的路线在configuration护照(代码B)之前。

我修改了这个例子: https : //github.com/rkusa/koa-passport-example来帮助解释我正在努力完成的事情。 上面的auth.js的精简版本如下:

const passport = require('koa-passport') const fetchUser = (() => { // This is an example! Use password hashing in your const user = { id: 1, username: 'test', password: 'test' } return async function() { return user } })() passport.serializeUser(function(user, done) { console.log("serializing") done(null, user.id) }) passport.deserializeUser(async function(id, done) { console.log("DEserializing") try { const user = await fetchUser() done(null, user) } catch(err) { done(err) } }) const LocalStrategy = require('passport-local').Strategy passport.use(new LocalStrategy(function(username, password, done) { console.log("asked for authentication") fetchUser() .then(user => { if (username === user.username && password === user.password) { done(null, user) } else { done(null, false) } }) .catch(err => done(err)) })) 

通过拆分公共和私有路由工作的server.js (代码A)的剥离版本如下所示:

 const Koa = require('koa') const app = new Koa() // trust proxy app.proxy = true // sessions const session = require('koa-session') app.keys = ['your-session-secret'] app.use(session({}, app)) // body parser const bodyParser = require('koa-bodyparser') app.use(bodyParser()) // authentication require('./auth') const passport = require('koa-passport') app.use(passport.initialize()) app.use(passport.session()) // routes const fs = require('fs') const route = require('koa-route') //public routes app.use(route.get('/login', (ctx) => { ctx.body = "LOGIN"; })); app.use(route.post('/login', passport.authenticate('local', { successRedirect: '/home', failureRedirect: '/login' }) )) app.use(route.get('/logout', function(ctx) { ctx.logout() ctx.redirect('/login') })) // Require authentication for now app.use(function(ctx, next) { if (ctx.isAuthenticated()) { console.log("authenticated user") return next() } else { console.log("unauthenticated user") ctx.redirect('/login') } }) //private route app.use(route.get('/home', function(ctx) { ctx.body = "home" })) // start server const port = process.env.PORT || 3000 app.listen(port, () => console.log('Server listening on', port)) 

需要的是上面的function,但是路由在authentication之前都被声明了,然后我们在后面捕获authentication请求。 我写了一个替代server.js (代码B)试图做到这一点:

 const Koa = require('koa') const app = new Koa() // trust proxy app.proxy = true // sessions const session = require('koa-session') app.keys = ['your-session-secret'] app.use(session({}, app)) // body parser const bodyParser = require('koa-bodyparser') app.use(bodyParser()) // routes const fs = require('fs') const route = require('koa-route') app.use(route.get('/login', (ctx) => { ctx.body = "LOGIN"; })); app.use(route.post('/login', async (ctx, next) => { ctx.id = 0; console.log(); console.log("login"); await next(); })) app.use(route.get('/home', async (ctx, next) => { ctx.id = 1; console.log(); console.log("home") await next(); ctx.body = "home"; })) app.use(route.get('/logout', async (ctx) => { ctx.logout(); ctx.redirect('/login') })) const port = process.env.PORT || 3000 app.listen(port, () => console.log('Server listening on', port)) // authentication require('./auth') const passport = require('koa-passport') app.use(passport.initialize()) app.use(passport.session()); auth = async (ctx, next) => { console.log("Check for authentication request") if (ctx.id === 0 && !ctx.isAuthenticated()) { //here I want to actually authenticate if request if for authentication. Previously this code would have been in the callback of the public route ie the post method for login passport.authenticate('local', { successRedirect: '/home', failureRedirect: '/login' }); } else { //middleware blocking access to other middlewares. Previously this would have been placed inside a non -async function and placed before all protected routes if (ctx.isAuthenticated()) { console.log("authenticated user") return next() } else { console.log("unauthenticated user") ctx.redirect('/login') } } } app.use(auth) //app.use(MW1) //app.use(MW2) 

在每个路由callback中,我添加一个id属性到ctx,其中ctx.id = 0表示请求是一个authentication请求。 问题:passport.authenticate不会被调用。

然后我添加一个中间件来检查请求的其余部分是否被authentication(与代码A相同)。 这部分工程,即我的私人路线/家redirect到/login,因为用户没有身份validation。

我有另一个问题是发送注销请求给出错误“ctx.logout不是一个函数”。 我想这是绑在passport.authenticate根本不会被调用的事实。

我使用Postman发送POST和GET而不是表单。

POST localhost:3000 / login?username = test&password = test

GET localhost:3000 / home

GET本地主机:3000 /注销