前端Node.js-Day39

Session 认证的局限性:

  • Session 认证机制需要配合 Cookie 才能实现。由于 Cookie 默认不支持跨域访问,所以,当涉及到前端跨域请求后端接口的时候,需要做很多额外的配置,才能实现跨域 Session 认证。
  • 当前端请求后端接口不存在跨域问题的时候,推荐使用 Session 身份认证机制。
  • 当前端需要跨域请求后端接口的时候,不推荐使用 Session 身份认证机制,推荐使用 JWT 认证机制

 

JWT(JSON Web Token)认证机制:跨域认证解决方案

JWT工作原理:将用户信息通过Token字符串的方式,保存在客户端浏览器中。服务器通过还原Token字符串的形式来认证用户身份。

 

 

JWT组成部分:Header头部、Payload有效荷载、Signature签名。

  • 三者以 . 分割。
  • Payload是真正的用户信息。是加密后的用户信息。
  • Header和Signature是安全性相关的部分,为了保证用户信息的安全性。

JWT使用方式:

  • 客户端会把JWT存储到localStoragesessionStorage
  • 此后客户端与服务端通信需要携带 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: '未知错误' })
})

 

Express中不允许连续调用两次res.send方法!

posted @ 2022-09-25 13:19  HM-7  阅读(48)  评论(0)    收藏  举报