使用 koa 和 passport 进行身份验证
using koa and passport for authenication
我正在使用 koa 和 passport 尝试实现中间件以防止在未通过身份验证时访问 URI。
var koa = require('koa');
var session = require('koa-generic-session');
var bodyParser = require('koa-bodyparser');
var koaRouter = require('koa-router');
var passport = require('koa-passport');
var views = require('co-views');
var render = views('.', { map: { html: 'swig' }});
var localStrategy = require('passport-local').Strategy;
var app = koa();
var router = koaRouter();
app.keys = ['secret'];
app.use(session());
app.use(bodyParser());
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
passport.use(new localStrategy(function(username, password, done) {
if (username === 'user1' && password === 'password2') {
done(null, { userId: 99, userName: 'redBallons' });
} else {
done(null, false);
}
}));
router.get('/login', function *(next) {
this.body = yield render('index.html');
});
router.post('/login', passport.authenticate('local', {
successRedirect: '/secretBankAccount',
failureRedirect: '/login'
}));
router.get('*', function *(next) {
if (! this.isAuthenticated()) {
console.log('not authenticated');
this.redirect('/login');
} else {
console.log('authenticated');
yield next;
}
});
router.get('/secretBankAccount', function *(next) {
this.body = '2 dollars';
});
app.use(router.routes());
app.listen(8080);
但是,我永远无法访问我的 secretBankAccount。我可以输入正确的用户名和密码,并且可以看到经过身份验证的消息,但是 router.get('*') 中的 yield next 不会将我传递到下一个路由函数
当使用 koa-router
时,预计只会命中一条路线。因此,当您到达 '*'
路线时,即使您 yield next
.
也不会到达另一条路线
所以你应该用自己的认证中间件替换通用路由:
app.use(function*(next) {
if (this.isAuthenticated()) {
yield next
} else {
this.redirect('/login')
}
});
身份验证中间件将强制您使用两个路由对象而不是一个来进行路由。这样您就可以区分 public 和安全路由。所以像:
var public = new koaRouter();
public.get('/login', function *(next) {
this.body = yield render('index.html');
});
public.post('/login', passport.authenticate('local', {
successRedirect: '/secretBankAccount',
failureRedirect: '/login'
}));
app.use(public.routes());
app.use(function*(next) {
if (this.isAuthenticated()) {
yield next;
} else {
this.redirect('/login');
}
})
var secured = new koaRouter();
secured.get('/secretBankAccount', function *(next) {
this.body = '2 dollars';
});
app.use(secured.routes());
在上面的示例中,请求将首先命中 public 路由中间件。然后,如果它与 public 路由的当前请求不匹配,它将移至身份验证中间件。如果 isAuthenticated()
是 false
将发生重定向。如果 isAuthenticated()
是 true
它将移动到安全路由。
此方法基于 the koa-passport-example project,由 koa-passport
的作者创建。
peadar-doyle 的回答是执行此操作的方法,但需要更新以避免警告:koa deprecated Support for generators will be removed in v3.
这是更新后的版本。我发送 401
而不是重定向:
// all requests must now be authenticated
app.use(async (ctx, next) => {
if (ctx.isAuthenticated()) {
await next();
} else {
ctx.body = "access denied";
ctx.status = 401;
}
})
我正在使用 koa 和 passport 尝试实现中间件以防止在未通过身份验证时访问 URI。
var koa = require('koa');
var session = require('koa-generic-session');
var bodyParser = require('koa-bodyparser');
var koaRouter = require('koa-router');
var passport = require('koa-passport');
var views = require('co-views');
var render = views('.', { map: { html: 'swig' }});
var localStrategy = require('passport-local').Strategy;
var app = koa();
var router = koaRouter();
app.keys = ['secret'];
app.use(session());
app.use(bodyParser());
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
passport.use(new localStrategy(function(username, password, done) {
if (username === 'user1' && password === 'password2') {
done(null, { userId: 99, userName: 'redBallons' });
} else {
done(null, false);
}
}));
router.get('/login', function *(next) {
this.body = yield render('index.html');
});
router.post('/login', passport.authenticate('local', {
successRedirect: '/secretBankAccount',
failureRedirect: '/login'
}));
router.get('*', function *(next) {
if (! this.isAuthenticated()) {
console.log('not authenticated');
this.redirect('/login');
} else {
console.log('authenticated');
yield next;
}
});
router.get('/secretBankAccount', function *(next) {
this.body = '2 dollars';
});
app.use(router.routes());
app.listen(8080);
但是,我永远无法访问我的 secretBankAccount。我可以输入正确的用户名和密码,并且可以看到经过身份验证的消息,但是 router.get('*') 中的 yield next 不会将我传递到下一个路由函数
当使用 koa-router
时,预计只会命中一条路线。因此,当您到达 '*'
路线时,即使您 yield next
.
所以你应该用自己的认证中间件替换通用路由:
app.use(function*(next) {
if (this.isAuthenticated()) {
yield next
} else {
this.redirect('/login')
}
});
身份验证中间件将强制您使用两个路由对象而不是一个来进行路由。这样您就可以区分 public 和安全路由。所以像:
var public = new koaRouter();
public.get('/login', function *(next) {
this.body = yield render('index.html');
});
public.post('/login', passport.authenticate('local', {
successRedirect: '/secretBankAccount',
failureRedirect: '/login'
}));
app.use(public.routes());
app.use(function*(next) {
if (this.isAuthenticated()) {
yield next;
} else {
this.redirect('/login');
}
})
var secured = new koaRouter();
secured.get('/secretBankAccount', function *(next) {
this.body = '2 dollars';
});
app.use(secured.routes());
在上面的示例中,请求将首先命中 public 路由中间件。然后,如果它与 public 路由的当前请求不匹配,它将移至身份验证中间件。如果 isAuthenticated()
是 false
将发生重定向。如果 isAuthenticated()
是 true
它将移动到安全路由。
此方法基于 the koa-passport-example project,由 koa-passport
的作者创建。
peadar-doyle 的回答是执行此操作的方法,但需要更新以避免警告:koa deprecated Support for generators will be removed in v3.
这是更新后的版本。我发送 401
而不是重定向:
// all requests must now be authenticated
app.use(async (ctx, next) => {
if (ctx.isAuthenticated()) {
await next();
} else {
ctx.body = "access denied";
ctx.status = 401;
}
})