身份验证是 Web 应用程序开发中必不可少的一部分。而 JWT(JSON Web Token)则是一种常用的身份验证方式,它使用 JSON 对象来传递信息,确保用户是否登录并进行授权。
在本文中,我们将介绍如何使用 JWT 进行身份验证,并给出 Koa 框架的实现方法。同时,我们将详细讲解 JWT 的工作原理,以及如何扩展和优化它的功能。
JWT 的工作原理
JWT 由三个部分组成:头部(Header)、载荷(Payload)和签名(Signature)。
头部(Header)
头部包含了两个部分:令牌的类型("typ": "JWT")和所使用的签名算法("alg": "HS256")。
载荷(Payload)
载荷包含了一些有关用户的信息,如用户 ID 和用户角色等。这个部分是任意的,你可以填入你需要的信息。但是要注意,不要将敏感信息放在这里。
签名(Signature)
签名由头部、载荷和密钥组成。它的作用是确保信息在传输过程中不被篡改。在服务器收到 JWT 后,会使用保存在服务器上的密钥对 JWT 进行解密,从而验证 JWT 是否合法。
使用 JWT 进行身份验证
下面我们就来介绍如何使用 JWT 进行身份验证。
生成 JWT
首先,我们需要在服务器上生成 JWT。我们可以使用第三方模块 jsonwebtoken
来生成 JWT。示例代码如下:
const jwt = require('jsonwebtoken'); const payload = { id: '12345', role: 'admin' }; const token = jwt.sign(payload, 'mysecretkey');
其中,payload 包含了一些有关用户的信息,这些信息将被编码为 JWT 的载荷,'mysecretkey'
是用于签名的密钥。
将 JWT 发送给客户端
接下来,我们需要将生成的 JWT 发送给客户端。在 Koa 框架中,我们可以通过设置响应头来实现:
ctx.set('Authorization', `Bearer ${token}`);
Bearer
是 JWT 的类型,后面跟着生成的 JWT。
验证 JWT
当客户端发送请求时,我们需要验证 JWT 是否合法。我们可以编写一个中间件函数来实现:
-- -------------------- ---- ------- ----- --- - ------------------------ ----- ------------ - -------- -- - ------ ----- ----- ----- -- - ----- ---------- - -------------------------- -- ------------ - ----- ------ ------ - ------------------ --- -- ----- --- --------- - --- - ----- ------- - ----------------- -------- -------------- - -------- ----- ------- - ----- ----- - ---------- - ---- -------- - - -------- -------- ------ -- - - ---- - ---------- - ---- -------- - - -------- -------------- ----- ---- ----- ---- ------- -- - - ---- - ---------- - ---- -------- - - -------- -------------- ------ --- ------ -- - -- --
上面这个函数是一个返回中间件函数的高阶函数,它的作用是验证请求头中的 JWT 是否合法。其中,secret
是用于签名的密钥。当 JWT 合法时,我们将解密后的用户信息保存到 Koa 的 ctx.state
对象中,以便之后的处理。
你可以在需要验证 JWT 的路由中使用这个中间件函数。示例代码如下:
const router = require('@koa/router')(); const authenticate = require('./middleware/authenticate'); router.get('/protected', authenticate('mysecretkey'), async (ctx) => { ctx.body = { message: 'Hello, ' + ctx.state.user.id + '!' }; });
在上面这个例子中,我们需要先验证用户是否登录,然后才能访问 /protected
路由。
扩展和优化 JWT 功能
使用 Refresh Token
为了提高安全性,我们可以使用 Refresh Token。参数 jwt.sign()
支持设置过期时间(expiresIn
属性),当 JWT 过期时,我们可以使用 Refresh Token 来获取新的 JWT。Refresh Token 可以保存在服务器上,或者保存在客户端的 cookie 中。
const refreshToken = jwt.sign(payload, 'myrefreshkey', { expiresIn: '7d' }); ctx.cookies.set('refreshToken', refreshToken, { httpOnly: true, maxAge: 86400 });
响应式 JWT
为了支持在多个设备上访问应用程序,可以使用响应式 JWT。我们可以在 JWT 的载荷中添加一个属性 jti
(JWT ID),当用户注销登录时,我们可以将这个属性的值添加到一个黑名单中,以确保 JWT 不能被使用。
const payload = { id: '12345', role: 'admin', jti: 'ABC123' }; const token = jwt.sign(payload, 'mysecretkey');
在 JWT 中存储更多信息
在 JWT 的载荷中,我们可以存储更多的信息,比如用户的权限、角色、过期时间等。这些信息可以让我们更灵活地使用 JWT。
const payload = { id: '12345', role: 'admin', permissions: ['create', 'update', 'delete'], exp: 1631313328 }; const token = jwt.sign(payload, 'mysecretkey');
总结
在本文中,我们介绍了如何使用 JWT 进行身份验证,并给出了 Koa 框架的实现方法。同时,我们讲解了 JWT 的工作原理,以及如何扩展和优化它的功能。
JWT 是一种简单且灵活的身份验证方式,它可以让我们在构建 Web 应用程序时更加简单和安全。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64b20cbb48841e9894e60efe