Restful API 使用 JWT 安全验证

背景

参考 开放api接口签名验证 ,REST接口安全认证方式对比:API Key vs OAuth令牌 vs JWT

微服务开发过程中,写开放的API接口时,可能会带来如下安全问题:

  • 请求源是否合法
  • 请求参数是否被篡改
  • 请求的唯一性

为了避免以上安全性问题,保证数据在通信时的安全性,我们需要验证使用者的身份。验证使用者身份有多种方式:session , token等。在微服务中,用户直接调用API获取资源,这时候就需要token来验证使用者身份,保护数据安全。这篇文章主要讲token ----json web token

以下内容摘自 以 JSON Web Token 替代傳統 Token

session

在传统网站中,会用session来辨别使用者身份,辨别使用者是否登陆。由于session只会被服务器端知道,所以可以在session中保存一些机密资料以供之后验证使用。

session存在的问题

  • 具状态性:假设有两台服务器 通过负载均衡 来互相处理 用户请求,由于session是存储在服务器端,第一次用户登陆时,由Server1 处理,那么session会存在Server1。如果下一次,用户请求 被负载均衡 指派Server2来处理,那么session在Server2不存在,所以用户就需要重新登陆一次。(这个问题可以解决,暂不讨论)
  • 容易受 跨网域请求伪造攻击:session存在服务器端,所以用户 在发送请求时几乎不用提供什么。所以很可能用户提供了一个删除文章的连接给服务器,服务器就删除了文章。

Token

Token可以解决  session 容易受 跨网域请求伪造攻击的问题,并且可以在多个服务器上 跨域使用。

  • 什么是token:用户登陆成功时,会得到一个数字字符串,这个串看起来毫无意义,可是对应资料库中使用者的身份。这个串就是token
  • 无状态性:当服务器接收到token时,会解密token,对比数据库,然后就会知道这个token是否合法,对应哪个用户,并获取这个用户的相关资料等。由于多个服务器共享一个 数据库,所以就不存在session 只存在 在一个服务器的问题。
  • 避免 受 跨网域请求伪造攻击:因为用户需要主动提供token,非法攻击 不会拥有合法的token,所以不能请求成功。

JWT  json web token 取代传统token

  • 相比token需要从数据库中比对用户是否合法,jwt 可以存放资料,不需要数据库来存储用户资料。直接把用户资料存放在「Token」中,所以也就省去了额外的数据库开销

JWT  json web token 的构成

  • Header 头部:JWT 的头部包含两部分,token类型和采用的加密算法。这些內容通过 Base64 编码就得到JWT的头部 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
{
  "alg": "HS256",
  "typ": "JWT"
}
  • Payload 负载:JWT的标准所定义的几个基本字段 + 我们在业务处理中需要用到的字段,如用户账号,昵称等,这样就不再需要去数据库找,不要放密码。将这部分通过 Base64 编码就得到第二段字符串 eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
  1. JWT的标准所定义的几个基本字段
  2. issuer: 该JWT的签发者
  3. subject: 该JWT所面向的用户
  4. audience: 接收该JWT的一方
  5. expiration(expires): 什么时候过期,这里是一个Unix时间戳
  6. issueAt(issued at): 在什么时候签发的
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
  • Signature 签名:这部分的算法是由上面两部分内容的 Base64 以點(.)組合起來,并以密码加密得到签名TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), "secret") 

以上3部分就组成了  json web token = 标题.内容.签名

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

由于生成签名的密码是存在服务器端的,所以就不怕别人篡改JWT,因为别人篡改的JWT 不会被服务器识别。

 

 

posted on 2020-06-19 16:06  dreamstar  阅读(923)  评论(0编辑  收藏  举报