下面的代码来自HapiJS文档,它描述了如何使用@hapi/cookie插件来使用会话和cookie。
'use strict';
const Hapi = require('@hapi/hapi');
const internals = {};
// Simulate database for demo
internals.users = [
{
id: 1,
name: 'john',
password: 'password',
},
];
internals.renderHtml = {
login: (message) => {
return `
<html><head><title>Login page</title></head><body>
${message ? '<h3>' + message + '</h3><br></a>' : ''}
<form method="post" action="/login">
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br></a>
<input type="submit" value="Login"></form>
</body></html>
`;
},
home: (name) => {
return `
<html><head><title>Login page</title></head><body>
<h3>Welcome ${name}! You are logged in!</h3>
<form method="get" action="/logout">
<input type="submit" value="Logout">
</form>
</body></html>
`;
}
};
internals.server = async function () {
const server = Hapi.server({ port: 8000 });
await server.register(require('@hapi/cookie'));
server.auth.strategy('session', 'cookie', {
cookie: {
name: 'sid-example',
// Don't forget to change it to your own secret password!
password: 'password-should-be-32-characters',
// For working via HTTP in localhost
isSecure: false
},
redirectTo: '/login',
validateFunc: async (request, session) => {
const account = internals.users.find((user) => (user.id === session.id));
if (!account) {
// Must return { valid: false } for invalid cookies
return { valid: false };
}
return { valid: true, credentials: account };
}
});
server.auth.default('session');
server.route([
{
method: 'GET',
path: '/',
options: {
handler: (request, h) => {
return internals.renderHtml.home(request.auth.credentials.name);
}
}
},
{
method: 'GET',
path: '/login',
options: {
auth: {
mode: 'try'
},
plugins: {
'hapi-auth-cookie': {
redirectTo: false
}
},
handler: async (request, h) => {
if (request.auth.isAuthenticated) {
return h.redirect('/');
}
return internals.renderHtml.login();
}
}
},
{
method: 'POST',
path: '/login',
options: {
auth: {
mode: 'try'
},
handler: async (request, h) => {
const { username, password } = request.payload;
if (!username || !password) {
return internals.renderHtml.login('Missing username or password');
}
// Try to find user with given credentials
const account = internals.users.find(
(user) => user.name === username && user.password === password
);
if (!account) {
return internals.renderHtml.login('Invalid username or password');
}
request.cookieAuth.set({ id: account.id });
return h.redirect('/');
}
}
},
{
method: 'GET',
path: '/logout',
options: {
handler: (request, h) => {
request.cookieAuth.clear();
return h.redirect('/');
}
}
}
]);
await server.start();
console.log(`Server started at: ${server.info.uri}`);
};
internals.start = async function() {
try {
await internals.server();
}
catch (err) {
console.error(err.stack);
process.exit(1);
}
};
internals.start();我的问题是:在POST登录路由中,在用户成功登录后,request.cookieAuth.set({ id: account.id });是否将{id:account.id}保存在内存中(缓存)并将其作为cookie发送给客户端?还是这里什么都没救?类似地,request.cookieAuth.clear();是否从内存和客户端清除会话??
发布于 2022-04-13 21:02:12
Hapi.js有自己的内存系统,但您也可以选择使用一些自定义的东西,比如Redis或其他商店。
我使用Hapi的商店,它在单个服务器实例中运行良好。如果您计划拥有一个服务器实例集群,则需要将存储此类数据的数据卸载到像Redis这样的后端存储区,否则如果连接不粘稠,它们将在每个请求中负载平衡,而且如果用户碰到没有缓存会话的服务器实例,则该用户似乎已被注销。使用同步后端缓存,所有服务器实例共享该缓存数据并保持同步。
这是我管理事情的方法。我会为会话密钥生成一个唯一的UUID,因为用户id是非常明显的。
export class AuthCookieData implements IAuthCookieData {
sid: string
constructor(data: IAuthCookieData) {
this.sid = data.sid;
}
}
export class AuthCookie {
/**
* accepts one parameter: account
* account: the user account to register as {username:'username', password:'password', email: 'user@email.com'}
* returns: Promise with new account
*/
static async setCookie(request: Hapi.Request, userProfile: UserProfile): Promise<void> {
var sid = uuid.v4();
await request.server.app['cache'].set(sid, userProfile, 0);
request['cookieAuth'].set(new AuthCookieData({ sid: sid }));
}
}
static async sessionCacheFunction(request: Hapi.Request, session: AuthCookieData) {
var userProfile: UserProfile = await request.server.app['cache'].get(session.sid);
if (!userProfile) {
return { valid: false };
} else {
return { valid: true, credentials: userProfile };
}
}
}const handler:Hapi.Lifecycle.Method = async (request: Hapi.Request, h: Hapi.ResponseToolkit) => {
if (request.auth.isAuthenticated) {
return request.auth.credentials;
}
const userProfile: UserProfile = await UserUtility.login(<ILogin>request.payload);
if (!userProfile) {
return Boom.badRequest('Could not authenticate. Username or password is invalid.');
}
AuthCookie.setCookie(request, userProfile);
return profile;
};server.auth.strategy('session', 'cookie', {
cookie: {
name: 'sid',
password: Configuration.auth.password,
isSecure: false,
clearInvalid: true
},
validateFunc: AuthCookie.sessionCacheFunction
}); https://stackoverflow.com/questions/67810882
复制相似问题