Skip to content

❤Node08-Express-jwt身份认证

1、token基本概念

Session认证的局限性

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

注意:

  • 当前端请求后端接口不存在跨域问题的时候,推荐使用 Session 身份认证机制。
  • 当前端需要跨域请求后端接口的时候,不推荐使用 Session 身份认证机制,推荐使用 JWT 认证机制。

什么是token

JWT(英文全称:JSON Web Token)是目前最流行的跨域认证解决方案。

jwt的原理

image.png

总结

  1. 用户的信息通过 Token 字符串的形式,保存在客户端浏览器中。
  2. 服务器通过还原 Token 字符串的形式来认证用户的身份。

jwt的组成

JWT 通常由三部分组成,分别是 Header(头部)、Payload(有效荷载)、Signature(签名)

三者之间使用英文的“.”分隔,格式如下:

plain
js
复制代码
Header.Payload.Signature

// 列如
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7Im5hbWUiOiJ6cyIsInBhc3N3b3JkIjoxMjN9LCJpYXQiOjE2Mzc1MDcyNzksImV4cCI6MTYzNzUxODA3OX0.0o9PCv-11SxM8TgMns--S0D-ZnidYZdXLk13V_B35B0

JWT的三个部分各自代表的含义

JWT 的三个组成部分,从前到后分别是 Header、Payload、Signature。

其中:

  • payload 部分才是真正的用户信息,它是用户信息经过加密之后生成的字符串。
  • HeaderSignature 是安全性相关的部分,只是为了保证 Token 的安全性。

image.png

jwt的使用方式

前端

  1. 客户端收到服务器返回的 JWT 之后,通常会将它储存在localStoragesessionStorage 中。
  2. 此后,客户端每次与服务器通信,都要带上这个 JWT 的字符串,从而进行身份认证。推荐的做法是把 JWT 放在 HTTP 请求头的 Authorization 字段中,格式如下:
js
Authorization: Bearer [token]

后端

  1. 登录成功, 生成token, 返回给浏览器
  2. 所有的接口中. 判断请求头是否携带了token(登录页面除外)

2、使用jwt

express-jwt 介绍和认识 (后面抽离为单个模块)

express-jwt的官网

https://www.tabnine.com/code/javascript/functions/express-jwt/expressJwt

1、简述

JWT ,全称JSON Web Token,本质就是一个字符串,它是将用户信息保存到一个Json字符串中,然后进行编码后得到一个JWT token,并且这个JWT token带有签名信息,接收后可以校验是否被篡改,所以可以用于在各方之间安全地将信息作为Json对象传输。

个人理解:其实本质上就是添加了一个安全性的签名然后用这个签名来校验是不是安全的。

express-jwt是express的中间件,用来解析请求对象的JWT负载。

2、简单用法

使用HS256加密的JWT:

javascript
var { expressjwt: jwt } = require("express-jwt");

app.get(
  "/protected",
  jwt({ secret: "helloworld", algorithms: ["HS256"] }),
  function (req, res) {
    if (!req.auth.admin) return res.sendStatus(401);
    res.sendStatus(200);
  }
);

3、express-jwt参数详解

expressjwt的参数列表如下:

secret:必须的参数,为字符串string类型 或者 GetVerificationKey函数接口

GetVerificationKey = (req: express.Request, token: jwt.Jwt | undefined) => Promise<jwt.Secret>;

getToken?:可选的参数,TokenGetter接收快速请求并返回令牌的函数,默认情况下它在Authorization头中查找。

isRevoked?:可选的参数,一个验证令牌是否被撤销的函数,函数接口如下:

IsRevoked = (req: express.Request, token: jwt.Jwt | undefined) => Promise; credentialsRequired?:可选的参数,类型为bool,当为false时,如果请求不包含令牌,则继续到下一个中间件,而不是失败,默认为true。 requestProperty?:可选的参数,类型为string,请求对象中设置有效负载的属性的名称。

4、安全漏洞

当提供第三方库作为机密时,需要使用算法参数来防止潜在的降级攻击。
不要混合使用对称算法和非对称算法(如HS256/RS256):在没有进一步验证的情况下混合使用算法可能会潜在地导致降级漏洞。

javascript
jwt({
  secret: "shhhhhhared-secret",
  algorithms: ["HS256"],
  //algorithms: ['RS256']
});

Released under the MIT License.