我正在使用hapi-auth-cookie来保护一些使用用户身份验证的路由。
server.auth.strategy('session', 'cookie', {
password : process.env.SESSION_COOKIE_PASSWORD,
cookie : 'sid',
clearInvalid : true,
isHttpOnly : true,
isSecure : true
});
如果用户已登录,某些路由会有特殊行为,但无论如何都应该可以访问和运行。
{
method : 'GET',
path : '/',
config : {
auth : {
strategy : 'session',
mode : 'optional'
}
},
handler(request, reply) {
if (request.auth.isAuthenticated) {
const { credentials } = request.auth;
reply(`Hello <pre>${credentials.name}</pre> <a href="/logout">Click here to log out</a>`);
}
else {
reply('Not logged in. <a href="/login">Click here to log in.</a>');
}
}
}
某些路由仅适用于已登录的用户,并且其他所有人都无法访问。
{
method : 'GET',
path : '/profile',
config : {
auth : {
strategy : 'session',
mode : 'required'
}
},
handler(request, reply) {
const { credentials } = request.auth;
reply(`This is your private profile: <pre>${JSON.stringify(credentials, null, 4)}</pre> <a href="/logout">Click here to log out</a>`);
}
}
除了如果我在没有登录的情况下访问/profile
之外,这两个工作都完美无缺,然后显示一条丑陋的401 Unauthorized
JSON消息。理想情况下,它只会让我登录。
所以我继续在会话策略中添加redirectTo : '/login'
。现在/profile
行为完美,并在必要时将我重定向到登录。不幸的是,/
路由也是如此,即使它是mode : optional
。文档确实提到try
模式的行为方式,我也正确地假设optional
。但是,这看起来非常愚蠢,这里的设置对于Web应用程序来说非常常见。
人们是如何做到这一点的?我想出了一些选择,我都不喜欢。
我自己在处理程序中实现重定向,这不是很干净。
覆盖每个mode : optional
路由的插件选项,这不是更好。
{
method : 'GET',
path : '/',
config : {
plugins : {
'hapi-auth-cookie' : {
redirectTo : false
}
},
auth : {
strategy : 'session',
mode : 'optional'
}
}
handler(request, reply) {
// ...
}
}
有两个具有不同配置的会话策略实例。因此会有session-optional
和session-required
。虽然我仍然需要在每条路线中指定mode
,这不是DRY。最重要的是,hapi-auth-cookie
似乎不想多次实例化。