关于JSON WEB TOKEN(JWT)的一些理解

JWTtoke的一种形式。主要由header(头部)、payload(载荷)、signature(签名) 这三部分字符串组成,这三部分使用"."进行连接,完整的一条JWT值为 h e a d e r . {header}. header.{payload}.${signature}

header

注明使用何种算法制作签名

最开始其实是一个json对象,该JSON包含alg和typ这两个属性,其中alg是签名算法类型,生成JWT中的signature部分时需要使用到,默认为HS256,而typ是当前token类型

{
  "alg": "HS256",
  "typ": "JWT"
}

paylod

实际讯息的JSON

payload中存放着7个官方定义的属性

iss:签发人
sub:主题
aud:受众
exp:过期时间
nbf:生效时间
iat:签发时间
jti:编号

signature

利用header注明的算法制作出来的乱码

signature会使用header中alg属性定义的签名算法,对header和payload合并的字符串进行加密,加密过后得到的字符串就是signature

提供一个制作JWT的网站

制作JWT
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XPR1Grk7-1615393869470)(https://github.com/stanedward1/MyPicture/blob/master/2103/JWT.png?raw=true)]

下面用ruby来演示相关操作

1.安装gem包并bundle

cd testdemo
gem install jwt
vim Gemfile # add gem 'jwt'
bundle

2.rails c下实践

# 没有设定签名算法类型

2.7.2 :005 > payload = {data: 'test'}
 => {:data=>"test"} 
2.7.2 :006 > token = JWT.encode payload, nil, 'none'
 => "eyJhbGciOiJub25lIn0.eyJkYXRhIjoidGVzdCJ9." 
2.7.2 :007 > puts token
eyJhbGciOiJub25lIn0.eyJkYXRhIjoidGVzdCJ9.
 => nil 
2.7.2 :008 > decoded_token = JWT.decode token, nil , false
 => [{"data"=>"test"}, {"alg"=>"none"}] 
2.7.2 :009 > puts decoded_token
{"data"=>"test"}
{"alg"=>"none"}
 => nil 
# 签名算法类型设为HS256(HMAC using SHA-256 hash algorithm)
# HS256 使用同一个「secret_key」进行签名与验证(对称加密)。一旦 secret_key 泄漏,就毫无# 安全性可言了。
# 因此 HS256 只适合集中式认证,签名和验证都必须由可信方进行。

2.7.2 :011 > hmac_secret = "my secret text"
 => "my secret text" 
2.7.2 :012 > token = JWT.encode payload, hmac_secret, 'HS256'
 => "eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.X-zKCN2I6HEvCUKysF3wNKzQ8MvpYhilh0GyA264dtQ" 
2.7.2 :013 > puts token
eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.X-zKCN2I6HEvCUKysF3wNKzQ8MvpYhilh0GyA264dtQ
 => nil 
2.7.2 :014 > decoded_token = JWT.decode token, hmac_secret, true, { algorithm: 'HS256' }
 => [{"data"=>"test"}, {"alg"=>"HS256"}] 
2.7.2 :015 > puts decoded_token
{"data"=>"test"}
{"alg"=>"HS256"}
 => nil 
2.7.2 :016 > token = JWT.encode payload, nil, 'HS256'
 => "eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.pVzcY2dX8JNM3LzIYeP2B1e1Wcpt1K3TWVvIYSF4x-o" 
2.7.2 :017 > puts token
eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.pVzcY2dX8JNM3LzIYeP2B1e1Wcpt1K3TWVvIYSF4x-o
 => nil 
2.7.2 :018 > decoded_token = JWT.decode token, nil, true, { algorithm: 'HS256' }
Traceback (most recent call last):
        1: from (irb):18
JWT::DecodeError (No verification key available)
2.7.2 :019 > puts decoded_token
{"data"=>"test"}
{"alg"=>"HS256"}
 => nil 
# RS256 是使用 RSA 私钥进行签名,使用 RSA 公钥进行验证。公钥即使泄漏也毫无影响,只要确保私钥安全# 就行。
# RS256 可以将验证委托给其他应用,只要将公钥给他们就行。
2.7.2 :021 > rsa_private = OpenSSL::PKey::RSA.generate 2048
 => #<OpenSSL::PKey::RSA:0x00007f848afd3570> 
2.7.2 :022 > rsa_public = rsa_private.public_key
 => #<OpenSSL::PKey::RSA:0x00007f848aee8fe8> 
2.7.2 :023 > token = JWT.encode payload, rsa_private, 'RS256'
 => "eyJhbGciOiJSUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.J3o8GKKn_0vt_SJl3WINHXgd_u88H... 
2.7.2 :024 > puts token
eyJhbGciOiJSUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.J3o8GKKn_0vt_SJl3WINHXgd_u88Hqiar8J5yRTSk_BiiaMduRV1xnkHcBd8A62O08eNQH7gPyPPw2H2RqOUMPg9mVYfTHdyXWKKYipNQ2VVU7lzrXYIwOCHuZhSfzfZHbrMEn7Jc-Tc4Lq0t4FqqUeppIQ-o6yy41DSX_xpGBZ78MqpymkPhtGo871EUU08CXkSPIR8UZHu6YR8WFO-ZlrywgZjeFp6gfGdyb0lev3bV65D2pJsbHOYHToTcHLIum-2EYlu9VVfOuBTn_KncYdPcHVmgPPDTCBL2r487uVW_neUZDoHVGnbhekho57hn7aV-sbC18JP7aQEBiqQOw
 => nil 
2.7.2 :025 > decoded_token = JWT.decode token, rsa_public, true, { algorithm: 'RS2
56' }
 => [{"data"=>"test"}, {"alg"=>"RS256"}] 
2.7.2 :026 > puts decoded_token
{"data"=>"test"}
{"alg"=>"RS256"}
 => nil 
# ES256 和 RS256 一样,都使用私钥签名,公钥验证。算法速度上差距也不大,但是它的签名长度相对短很# 多(省流量),并且算法强度和 RS256 差不多。
2.7.2 :027 > ecdsa_key = OpenSSL::PKey::EC.new 'prime256v1'
 => #<OpenSSL::PKey::EC:0x00007f848a297ac8> 
2.7.2 :028 > ecdsa_key.generate_key
 => #<OpenSSL::PKey::EC:0x00007f848a297ac8> 
2.7.2 :029 > ecdsa_public = OpenSSL::PKey::EC.new ecdsa_key
 => #<OpenSSL::PKey::EC:0x00007f8489f75340> 
2.7.2 :030 > ecdsa_public.private_key = nil
 => nil 
2.7.2 :031 > token = JWT.encode payload, ecdsa_key, 'ES256'
 => "eyJhbGciOiJFUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.SCYVfzGZ1VtSHuiJhIdEhsEjE_GzU... 
2.7.2 :032 > puts token
eyJhbGciOiJFUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.SCYVfzGZ1VtSHuiJhIdEhsEjE_GzUKqDvWMa7By7jc4gtDDvVJss7_s1SCAeBcar2QKNoKy6pN9fSbcYCtFEzw
 => nil 
2.7.2 :033 > decoded_token = JWT.decode token, ecdsa_public, true, { algorithm: 'E
S256' }
 => [{"data"=>"test"}, {"alg"=>"ES256"}] 
2.7.2 :034 > puts decoded_token
{"data"=>"test"}
{"alg"=>"ES256"}
 => nil 

以上三种算法便是JWT中常用的几种算法,并附上我在简书上看到的一个例子!

JWT 构建Rails API 授权登录

本篇文章由一文多发平台ArtiPub自动发布

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值