1. 程式人生 > >Rust : Json Web Token

Rust : Json Web Token

JWT的原理

見相關資料:
https://zhuanlan.zhihu.com/p/27370773
https://zhuanlan.zhihu.com/p/43094841

原理:

三部分:頭部(header)載荷(payload)簽證(sign)

其中載荷中:
標準中註冊的宣告:
iss:jwt簽發者
sub:jwt所面向的使用者
aud:接收jwt的一方
exp:jwt的過期時間,這個過期時間必須大於簽發時間
nbf:定義在什麼時間之前,該token都是不可用的
iat:jwt的簽發時間
jti:jwt的唯一身份標識,避免重複



JWT的相關特點

優點
> 不需要儲存在伺服器的session中,更容易擴充套件伺服器由於使用者資訊可以放入token中,所以可以少了一次資料庫 / 快取的查詢操作,有更好的效能不需要預防CSRF的攻擊

不足
> token一經洩露或者被盜取,將會暴露該使用者

建議

> token的過期時間,不宜過長
> 非常重要的操作,需要手機驗證碼,支付密碼等二次驗證作為保險 
> 儘量使用 https


https://zhuanlan.zhihu.com/p/43094841
// Header
{
  "alg": "HS256",
  "typ": "JWT"
}

// Payload負載: iss(簽發者),exp(過期時間戳), sub(面向的使用者), aud(接收方), iat(簽發時間)
{
  "iss": "a.com",
  "exp": "1d",
  "http://a.com": true,
  "company": "A",
  "awesome": true
}

// Signature
HS256(Base64(Header) + "." + Base64(Payload), secretKey)

// JWT
JWT = Base64(Header) + "." + Base64(Payload) + "." + $Signature

Rust中JWT的庫見https://github.com/Keats/jsonwebtoken。
相關庫的樣例程式碼如下:

use std::{thread, time};
extern crate jsonwebtoken as jwt;
#[macro_use]
extern crate serde_derive;

use jwt::errors::ErrorKind;
use jwt::{decode, encode, Algorithm, Header, Validation};

#[derive(Debug, Serialize, Deserialize)]
struct Claims {
    sub: String,
    company: String,
    exp: usize,
}

fn main() {
    let sleep_seconds = time::Duration::from_secs(1000);
    let my_claims = Claims {
        sub: "
[email protected]
".to_owned(), company: "ACME".to_owned(), exp: 10000000000, }; let key = "secret"; let mut header = Header::default(); header.kid = Some("signing_key".to_owned()); header.alg = Algorithm::HS512; let token = match encode(&header, &my_claims, key.as_ref()) { Ok(t) => t, Err(_) => panic!(), // in practice you would return the error }; println!("token:{:?}", token); let token_data = match decode::<Claims>(&token, key.as_ref(), &Validation::new(Algorithm::HS512)) { Ok(c) => c, Err(err) => match *err.kind() { ErrorKind::InvalidToken => panic!(), // Example on how to handle a specific error _ => panic!(), }, }; println!("claims:{:?}", token_data.claims); println!("header:{:?}", token_data.header); println!("jwt, i am learning it!"); thread::sleep(sleep_seconds); }