Session 认证的局限性:
- Session 认证机制需要配合 Cookie 才能实现。由于 Cookie 默认不支持跨域访问,所以,当涉及到前端跨域请求后端接口的时候,需要做很多额外的配置,才能实现跨域 Session 认证。
- 当前端请求后端接口不存在跨域问题的时候,推荐使用 Session 身份认证机制。
- 当前端需要跨域请求后端接口的时候,不推荐使用 Session 身份认证机制,推荐使用 JWT 认证机制
JWT(JSON Web Token)认证机制:跨域认证解决方案
JWT工作原理:将用户信息通过Token字符串的方式,保存在客户端浏览器中。服务器通过还原Token字符串的形式来认证用户身份。
JWT组成部分:Header头部、Payload有效荷载、Signature签名。
- 三者以 . 分割。
- Payload是真正的用户信息。是加密后的用户信息。
- Header和Signature是安全性相关的部分,为了保证用户信息的安全性。
JWT使用方式:
- 客户端会把JWT存储到localStorage和sessionStorage中
- 此后客户端与服务端通信需要携带 JWT 进行身份认证,将 JWT 存到HTTP 请求头 Authorization 字段中
Express使用JWT:
1.安装JWT:npm install jsonwebtoken express-jwt
jsonwebtoken:用于生成JWT字符串
express-jwt:用于将JWT字符串还原成JSON对象
2.定义Secret密钥:
- 为保证 JWT 字符串的安全性,防止其在网络传输过程中被破解,需定义用于加密和解密的 secret 密钥
- 生成 JWT 字符串时,使用密钥加密信息,得到加密好的 JWT 字符串
- 把 JWT 字符串解析还原成 JSON 对象时,使用密钥解密
const jwt = require('jsonwebtoken') const expressJWT = require('express-jwt') // 定义secret密钥 const secretKey = 'LWH_LWH_LWH'
3.生成JWT字符串:调用jsonwebtoken中的sign方法(参数分别为:用户信息对象,加密密钥,配置对象可以通过expiresIn属性设置该Token的有效期)
// 登录成功后调用jwt的sign方法生成jwt字符串,并通过token属性发送给客户端 const tokenStr = jwt.sign({ username: userinfo.username }, secretKey, { expiresIn: '30s' }) res.send({ status: 200, message: '登陆成功', token: tokenStr //发送给客户端的token字符串 })
4.将JWT字符串还原为JSON对象:
- 客户端访问有权限的接口时,需通过请求头的
Authorization
字段,将 Token 字符串发送到服务器进行身份认证 - 服务器可以通过 express-jwt 中间件将客户端发送过来的 Token 解析还原成 JSON 对象
// 使用app.use注册中间件 // expressJWT({secret: secretKey}) 用来解析Token的中间件 // .unless({path: [/^\/api\//]}) 用来指定哪些接口不需要访问权限 app.use(expressJWT.expressjwt({ secret: secretKey, algorithms: ["HS256c"] }).unless({ path: [/^\/api\//] }))
5.获取用户信息:express-jwt配置成功后,使用req.auth属性来访问从JWT中解析的用户信息
获取信息时要设置响应头的Authorization
属性为Bearer加上post生成的Token值。
Authorization: Bearer <token>
app.get('/admin/getinfo', (req, res) => { console.log(req.auth); res.send({ status: 200, message: '获取用户信息成功!', data: { username: req.auth.username } }) })
6.捕获解析JWT失败后产生的错误:
- 当express-jwt解析Token时,如果客户端发送的Token过期或不合法,会产生解析失败的错误。
- 通过Express的错误中间件捕获该错误。
// 捕获Token解析的错误 app.use((err, req, res, next) => { if (err.name === 'UnauthorizedError') { return res.send({ status: 401, message: '无效的Token' }) } res.send({ status: 500, message: '未知错误' }) })
标签:Node,Day39,JWT,jwt,js,Token,字符串,认证,客户端 From: https://www.cnblogs.com/LWHCoding/p/16727711.html