Hapi.js 是一个流行的 Node.js Web 框架,它提供了强大的生态系统和丰富的功能。在 Hapi.js 中,生命周期方法是不可或缺的一部分,它们负责处理请求和响应的不同阶段。本文将深入介绍 Hapi.js 生命周期方法并提供一些示例代码。
生命周期方法的概述
在 Hapi.js 中,生命周期方法代表请求和响应的不同阶段。每个请求都会依次经过多个阶段,每个阶段都有一个或多个生命周期方法。这些方法通常在初始化时注册,然后按照特定的顺序执行。以下是 Hapi.js 中常见的生命周期方法:
onPreAuth: 这个方法在验证用户身份之前运行。在这个阶段,我们可以进行任何预处理,例如解密加密的输入数据。onCredentials: 这个方法在验证用户身份之后运行。在这个阶段,我们可以设置与用户关联的凭据,例如通过解码 JSON Web 令牌。onPreHandler: 这个方法在处理请求处理程序之前运行。在这个阶段,我们可以进行一些业务逻辑处理。onPostHandler: 这个方法在处理请求处理程序之后运行,但在响应被发送给客户端之前。在这个阶段,我们可以对响应进行任何修改。onPreResponse: 这个方法在响应发送给客户端之前运行。在这个阶段,我们可以访问响应的状态码、头信息和负载,并在需要时进行修改。
生命周期方法的使用
在使用 Hapi.js 生命周期方法时,我们首先需要确定哪些方法在特定的上下文中应该运行。我们可以使用路由选项的 lifecycle 参数来指定这些方法。例如,如果要在路由中注册 onPreAuth 方法,我们可以像这样编写代码:
// www.javascriptcn.com code example
server.route({
method: 'GET',
path: '/',
handler: function (request, h) {
return 'Hello, world!';
},
options: {
lifecycle: {
onPreAuth: async function (request, h) {
await doSomething();
return h.continue;
}
}
}
});在这个例子中,我们在 options 对象中指定了 lifecycle 选项,并传入了一个包含 onPreAuth 方法的对象。注意,在处理程序函数中,我们必须输出一个响应对象或调用 h.continue 方法继续执行下一个生命周期方法。
生命周期方法的示例
下面的示例演示了如何在 Hapi.js 中使用生命周期方法来实现身份验证和授权功能。这个例子假设我们有一个用户数据库和一个 secret 数据库,我们想使用 JSON Web 令牌来验证并授权用户访问 secret 数据库。
// www.javascriptcn.com code example
const Hapi = require('@hapi/hapi');
const Joi = require('joi');
const jwt = require('jsonwebtoken');
const users = [
{ id: 1, username: 'alice', password: 'secret123', email: 'alice@example.com' },
{ id: 2, username: 'bob', password: 'password456', email: 'bob@example.com' }
];
const secrets = [
{ id: 1, title: 'Top secret!', content: 'This is the most secret information of all.' },
{ id: 2, title: 'Not so secret', content: 'This is just some random information.' }
];
const secretKey = 'mysecretkey';
const validateUser = async function (decoded, request) {
const user = users.find(u => u.id === decoded.id);
if (user) {
return { isValid: true, credentials: user };
} else {
return { isValid: false };
}
};
const server = Hapi.server({
port: 3000,
host: 'localhost'
});
const start = async function () {
await server.register(require('hapi-auth-jwt2'));
server.auth.strategy('jwt', 'jwt', {
key: secretKey,
validate: validateUser,
verifyOptions: { algorithms: ['HS256'] }
});
server.route([
{
method: 'POST',
path: '/login',
handler: async function (request, h) {
const { username, password } = request.payload;
const user = users.find(u => u.username === username && u.password === password);
if (user) {
const token = jwt.sign({ id: user.id }, secretKey, { expiresIn: '1d' });
return h.response({ token }).code(201);
} else {
return h.response('Invalid credentials').code(401);
}
},
options: {
auth: false
}
},
{
method: 'GET',
path: '/secrets',
handler: async function (request, h) {
const { credentials: user } = request.auth;
if (!user) {
return h.response('Unauthorized').code(401);
}
const { id } = request.params;
if (!id) {
return h.response(secrets).code(200);
}
const secret = secrets.find(s => s.id === parseInt(id));
if (!secret) {
return h.response('Secret not found').code(404);
}
return h.response(secret).code(200);
},
options: {
auth: 'jwt',
validate: {
params: Joi.object({
id: Joi.number().integer().min(1).label('Secret ID')
}).and('id')
}
}
}
]);
await server.start();
console.log(`Server running at: ${server.info.uri}`);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
start();在这个例子中,我们首先定义了两个数组,一个表示用户,另一个表示 secret。然后,我们定义了一个用于验证用户的函数 validateUser。这个函数检查传入的 JSON Web 令牌并返回一个包含有效性和凭据的对象。如果令牌无效,它将返回 isValid: false。接下来,我们创建了一个 Hapi.js 服务器,并使用 hapi-auth-jwt2 插件注册了一个名为 jwt 的身份验证策略。在我们的路由定义中,我们指定了登录和查看 secret 的路由,每个路由都有不同的选项。登录路由使用 auth: false 选项来禁用身份验证,而查看 secret 的路由使用 auth: 'jwt' 选项启用身份验证,并使用 validate 选项来验证路由参数。
总之,生命周期方法是 Hapi.js 框架中强大的工具,它们提供了对请求和响应流程的细粒度控制,并使我们能够编写灵活而可扩展的应用程序。在这篇文章中,我们深入介绍了这个概念,并提供了一个示例代码来演示如何在 Hapi.js 中使用生命周期方法。希望这篇文章对您有所帮助,提高您的前端开发技能。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d5ea9ea941bf7134b4ad84