身份验证是现代 web 应用程序的重要组成部分。 Hapi 是一个强大的 Node.js web 应用程序框架,它提供了许多有用的工具和插件来帮助我们构建安全的应用程序。与此同时,JWT 是一种可扩展的身份验证协议,它被广泛用于保护 web 应用程序中的敏感信息。在本文中,我们将探讨如何在 Hapi 中使用 JWT 实现身份验证。
安装和准备工作
在开始之前,我们需要确保已经安装了 Node.js 环境和 npm。然后我们可以在终端中使用以下命令安装 Hapi 和 JWT:
npm install hapi jsonwebtoken
实现身份验证
我们可以使用 Hapi 和 JWT 实现身份验证的流程如下:
- 用户通过用户名和密码进行身份验证
- 如果凭据验证通过,则为用户颁发 JSON Web Token
- 用户将 JWT 作为请求的 Authorization 标头发送给服务器
- 服务器解码 JWT 并确定用户是否已经通过身份验证
让我们来看看如何在 Hapi 中实现这些步骤。
建立路由
首先,我们需要建立一个用于用户身份验证的路由。在这个例子中,我们将使用 /login 路径来处理身份验证请求,并将用户名和密码作为 POST 请求的负载。
server.route({
method: 'POST',
path: '/login',
handler: async (request, h) => {
// 实现身份验证
}
});实现身份验证
在路由中,我们需要实现身份验证。我们可以使用一个简单的函数来检查用户提供的用户名和密码是否与预期值匹配。
const validate = async (username, password) => {
// 在这里实现实际的用户验证
const isValid = username === 'admin' && password === 'password';
return isValid;
};如果用户名和密码验证成功,我们将为用户签发 JWT。
const token = await jwt.sign({ username }, 'my-secret-key');在这里,我们使用了 jsonwebtoken 库的 sign 方法来签发 JWT。第一个参数是要编码的数据对象,第二个参数是我们密钥的字符串。
发送 JWT
当我们从 /login 路由成功返回 JWT 时,我们可以在客户端中将其用作 Authorization 头的 Bearer token。在这个例子中,我们可以将它存储在浏览器 cookie 中,以在未来的请求中发回服务器。
const setAuthCookie = (token) => {
document.cookie = `authToken=${token}`;
};身份验证中间件
继续前面的流程,我们需要先解码 JWT,并确保它已经被正确签发才能响应任何请求。
// www.javascriptcn.com code example
const validateToken = async (decoded, request, h) => {
// 判断 JWT 是否有效
const isValid = decoded.username === 'admin';
if (!isValid) {
return { isValid: false };
}
return { isValid: true };
};
server.auth.strategy('jwt', 'jwt', {
key: 'my-secret-key',
validate: validateToken,
verifyOptions: { algorithms: ['HS256'] }
});
server.auth.default('jwt');在这里,我们使用 hapi-auth-jwt2 插件来提供 JWT 身份验证策略。我们使用 key 参数设置签名秘钥,validate 参数将用户定义的验证函数分配给 JWT。
保护路由
在下一步中,我们需要保护那些需要身份验证的路由。 这可以通过在路由配置中添加 auth 配置项来实现。
// www.javascriptcn.com code example
server.route({
method: 'GET',
path: '/protected',
options: {
auth: 'jwt',
},
handler: async (request, h) => {
// 在这里处理受保护的请求
return 'SUCCESS';
}
});在这里,我们将 auth 配置选项设置为 jwt,以指示需要进行身份验证才能访问此路由。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d7e86ba941bf7134e239c1