golang JWT原理介绍

JWT认证机制

官方文档

JWT文档

原理简介

客户端通过服务端认证之后,由服务端返回一个JSON对象,发回到客户端。客户端保存该对象用于以后服务器访问凭据,服务端完全依赖该JSON对象来验证客户端的身份。由于JSON数据容易被篡改,因此在服务器生成该对象之后会对该对象进行签名,防止数据被篡改。JWT token校验,基于token本身携带的内容和密钥

应用场景

  • 充当认证令牌,替代传统的session数据存储,通过jwt完全的依赖客户端保存认证信息

  • 基于jwt可携带数据的特性,可将其用于数据传输、信息交换的场景

JWT构成

jwt结构分为三个部分,Header、Payload、Signature

  • Header:Algorithm(算法),即签名算法。

  • Payload:存储信息的JSON对象

  • Signature:Payload基于Header指定算法的签名结果

  • Header与Payload部分,本身并没有被加密,而是做了Base64URL 编码。

  • Base64URL与Base64算法类似,Base64中+、/和= 在URL中有特殊含义,因此Base64URL 对它们做了处理

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

如上面的例子所示,JWT就是一个字符串,由三部分构成:

  • Header(头部)
  • Payload(数据)
  • Signature(签名)
header

JWT的头部承载两个信息:

  • 声明类型,这里是JWT
  • 声明加密的算法
{
  'typ': 'JWT',
  'alg': 'HS256'
}

然后将头部进行Base64编码(该编码是可以对称解码的),构成了第一部分。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
payload

载荷就是存放有效信息的地方。定义细节如下:

iss:令牌颁发者。表示该令牌由谁创建,该声明是一个字符串
sub:  Subject Identifier,iss提供的终端用户的标识,在iss范围内唯一,最长为255个ASCII个字符,区分大小写
aud:Audience(s),令牌的受众,分大小写的字符串数组
exp:Expiration time,令牌的过期时间戳。超过此时间的token会作废, 该声明是一个整数,是1970年1月1日以来的秒数
iat: 令牌的颁发时间,该声明是一个整数,是1970年1月1日以来的秒数
jti: 令牌的唯一标识,该声明的值在令牌颁发者创建的每一个令牌中都是唯一的,为了防止冲突,它通常是一个密码学随机值。这个值相当于向结构化令牌中加入了一个攻击者无法获得的随机熵组件,有利于防止令牌猜测攻击和重放攻击。
aud(audience): 受众
nbf(Not Before): 生效时间

也可以新增用户系统需要使用的自定义字段

然后将其进行Base64编码,得到Jwt的第二部分:

JTdCJTBBJTIwJTIwJTIyc3ViJTIyJTNBJTIwJTIyMTIzNDU2Nzg5MCUyMiUyQyUwQSUyMCUyMCUyMm5hbWUlMjIlM0ElMjAlMjJKb2huJTIwRG9lJTIyJTBBJTdE
Signature

这个部分需要Base64编码后的Header和Base64编码后的Payload使用 . 连接组成的字符串,然后通过Header中声明的加密方式进行加密($secret 表示用户的私钥),然后就构成了jwt的第三部分。

// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, '$secret');

将这三部分用 . 连接成一个完整的字符串,就构成了 jwt

JWT几个特点
  1. JWT 默认是不加密,不能将秘密数据写入 JWT。
  2. JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。
  3. JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
  4. 为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用HTTPS 协议传输。

加密和签名的区别

  • 加密是可逆的,签名是不可逆的
  • 非对称加密:公钥加密,私钥解密
  • 非对称签名:私钥签名,公钥验签(同样的算法对数据做签名,得到的签名是一样的)

你可能感兴趣的:(golang,开发语言,后端,安全)