在前端应用中,我们经常需要对用户的权限进行限制。Hapi 框架是一个流行的 Node.js 框架,它有很方便的插件来配合 JSON Web Token(JWT)做权限控制。JWT 是一种在网络应用中传递信息的标准。本文将详细介绍如何在 Hapi 框架中使用 JWT 来做权限控制。
什么是 JWT?
JWT 是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式传输信息。在 JWT 中,实体(通常指用户)将信息包装在 JSON 对象中,并使用密钥加密,然后将其转换为字符串格式。以后,实体可以通过传递 JWT 来验证其身份。已加密的 JWT 中的信息不能修改,因此它是一种安全且可靠的身份验证方法。
Hapi 插件:hapi-auth-jwt2
在 Hapi 中,我们可以使用 hapi-auth-jwt2 插件来完成 JWT 的验证。
安装 hapi-auth-jwt2
首先,在您的项目中安装 hapi-auth-jwt2:
npm install hapi-auth-jwt2
配置 JWT 策略
在您的 Hapi 服务器初始化代码中,需要配置要使用的 JWT 策略。以下是一个例子:
-- -------------------- ---- ------- ------------------------------------------ -------- ----- - -- ----- - ----- ---- - --------------------------- ------ - ---- --------------------------------------- ------------- --------- -------------- - ----------- - ------- - - --- -------------- ------- ------ ----- -------------- ------- - ----- ------ -------- -------- --------- ------ - ----------------- ------- - - --- ---
在这个例子中,我们先调用 Hapi 的 server.register
方法来注册 hapi-auth-jwt2 插件。 然后,我们使用 server.auth.strategy
方法来定义一个名为“jwt”的策略。 在这里,我们需要指定:
key
:JWT 的密钥,用于验证 JWT 的有效性。validateFunc
:用于验证 JWT 中的信息是否已验证成功的函数。这个函数需要接收两个参数,即 JWT 从中解析出的载荷和“回调”函数。回调函数应该在传入的载荷上回调以指示验证成功或失败。以下是一个validateFunc
的例子:
function validate(decoded, request, callback) { // 在这里,您需要编写实际的验证逻辑。 // 如果你检查载荷并发现它是有效的,就调用回调函数: return callback(null, true, decoded); }
verifyOptions
:这是 JSON Web Tokens 库所需的验证选项。 在这里,我们使用诸如“ALG”(算法)之类的选项来指定要使用的加密算法(在此示例中为 HS256)。auth
:用于指定在路由级别上使用此策略。
之后,我们使用 server.route
定义了一个只能由已经验证过 JWT 的用户访问的路由。在这个例子中,我们设置了 auth
参数以指定使用名为“jwt”的策略。 如果用户未在访问此路由时提供有效的 JWT,则该插件将返回一个验证错误。如果用户提供一个有效的 JWT,那么该路由就会被执行。 在这种情况下,它只是返回了一个字符串:“restricted data”。
这只是一个简单的例子,但它演示了如何在 Hapi 中使用 JWT 做权限控制。 在实际的应用程序中,您可能需要:
- 在载荷中包含更多的用户数据,例如用户的角色、访问权限等。
- 将策略与数据库中的用户集成起来。
- 定义更多策略来处理不同的身份验证情况。
示例代码
以下是更完整的代码示例,演示了如何在 Hapi 中使用 JWT 做权限控制。这个例子使用 MongoDB 作为数据库。在这个例子中,我们实现了两个路由:
/token
:这是验证用户身份的入口点。 它需要一个包含用户名和密码的正文。 如果用户名和密码有效,则返回一个 JWT。/restricted
:这是一个受限的路由,需要 JWT 才能访问。
-- -------------------- ---- ------- ----- ---- - ---------------- ----- --- - ------------------------ ----- ------- - ------------------- ----- ------ - ------------------ ----- ----- - --------------------------- ----- ------- - -------------------------- ----- ------ - --- -------------- ------------------------ ------- -- - -------- ---- ------- ----- ----- ---------------- - ----------------------------------- -- ------ ----- -- - -------------------------- -- ---- ----- -------- - -------------------------- -- -------------- ----------------- - --------- -------- --------- --------------------------- ---- ----- ------- -- - --------- ------- --------- --------------------------- --- - -- ----- ----- -- - -- ----- - ----------------- --------------- - ------------------- ----- ----- -- --- ----------- --- -- -- ------ ------ ---------------------- ----- -- - ------------------------------ -------- - ------------- -------- --- -- ---- -------------- - ------- ------- ----- --------- ------- - ----- -------- -- -------- ------------ -- - ------- ------ ----- -------------- ------- - ----- ----- -- -------- ----------------- - --- -- -- ------- ---- --- ------------------------ ----- -- - --------------------------- ------ - ---- --------------------------------------- ------------- --------- -------------- - ----------- - ------- - - --- --- ------------------ -- - ------------------- ------- ----- ----------------- --- --- -- -------- -------- -------- --------- --------- --------- --------- - --------------------------- ---------- ----- -------- -- - -- ----- - -------------- ------- - -- -------- -- ---------------------------- ------------------ - ------ ----------------- -------------- ----- --------- - ---- - -------------- ------- - --- - -- -- --- --------- -------- ------------ --------- ------ - ----- ----- - ---------- ---- --------------------------------- -- --------------------------------------- - ---------- -- - -- -- ---- --- ------------- -------- - -- ----- -------- ----------------- --------- ------ - -------------- -- --- ---------- -------- -
可以使用 Postman 来测试此示例。 在请求头中,将“Content-Type”设置为“application/json” , 在正文中输入包含用户名和密码的 JSON 对象,例如:
{ "username": "admin", "password": "password" }
发生 GET 请求到 /token
,您应该得到如下所示的 JSON 响应:
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImlhdCI6MTU1ODk1MzYzNywiZXhwIjoxNTU4OTU3MjM3fQ.kSbSoyrhshxhFlZc48Q-FoisC5UnhG2X7zz5z5E5Wt8" }
现在,您可以使用此 JWT 来访问 /restricted
路径。 为此,请向 GET 请求添加一个“Authorization”标头,如下所示:
Authorization: Bearer <YOUR_JWT_TOKEN>
如果 JWT 有效,则应看到以下响应:
Welcome to the restricted area!
如果 JWT 无效,则插件将返回一个验证错误。
总结
在本文中,我们介绍了如何在 Hapi 框架中使用 JWT 来做权限控制。我们学习了 hapi-auth-jwt2 插件,以及如何配置 JWT 策略。我们还提供了一个完整的示例代码,用于演示如何将 JWT 集成到基于 Hapi 的 Node.js 应用中。现在,您可以在自己的项目中使用 Hapi 和 JWT 做权限控制了!
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64a2342948841e9894e81851