JWT
- JWT
- https://openid.net/developers/jwt/
- https://mkjwk.org/
- 生成 JWK
 
- 是一套认证协议
- 协议简单且易于实现
- 主要用于分布式的无状态接口调用
https://auth0.com/blog/cookies-vs-tokens-definitive-guide/
强项
- 快速开发
- 不需要 Cookie
- JSON 相对友好
- 不依赖社交登陆
- 概念简单易于理解
限制
- Token 有大小限制
- Token 不能被回收
- 需要 Token 有个较短的失效周期
claims
- 声明
标准
| field | stand for | meanning | 
|---|---|---|
| iss | Issuer | 发出者 | 
| sub | Subject | 一般为用户 id | 
| aud | Audience | 接受者 | 
| exp | Expiration time | 失效时间 | 
| nbf | Not before | 在这之前不生效 | 
| iat | Issued at | 发出时间 | 
| jti | JWT ID | 
OIDC
| claim | for | note | 
|---|---|---|
| azp | Authorized party | 通常是 OAuth 2.0 客户端 ID | 
| nonce | CSRF | |
| acr | Authentication Context Class Reference | 用户怎么做的认证 | 
| sid | Session ID | |
| at_hash | Access Token Hash | 验证 Access Token 未被篡改 | 
| c_hash | Code hash value | |
| amr | Authentication Methods References | |
| sub_jwk | Subject public key | |
| auth_time | ||
| name | Full name | |
| middle_name | ||
| preferred_username | ||
| family_name | ||
| given_name | ||
| nickname | ||
| profile | url | |
| picture | url | |
| website | Web page or blog URL | |
| email_verified | boolean | |
| gender | ||
| birthdate | ||
| zoneinfo | ||
| locale | ||
| phone_number | ||
| phone_number_verified | boolean | |
| address | ||
| updated_at | ||
| s_hash | State Hash | OAuth 2.0 state 参数的哈希值 | 
自定义
| claim | for | 
|---|---|
| admin | |
| typ | Type 类型,由用户扩展, e.g. ID | 
- Keycloak
- realm_access, resource_access
- roles
 
 
- realm_access, resource_access
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022,
  "https://hasura.io/jwt/claims": {
    "x-hasura-allowed-roles": ["user", "anonymous"],
    "x-hasura-default-role": "user",
    "x-hasura-user-id": "1234567890",
    "x-hasura-org-id": "123",
    "x-hasura-custom": "custom-value"
  }
}
- https://www.iana.org/assignments/jwt/jwt.xhtml#claims
- https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-token-claims
scope
- openid
- profile
- name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, updated_at
 
- email
- email, email_verified
 
- address
- address
 
- phone
- phone_number , phone_number_verified
 
- offline_access
常见算法
- HMAC + SHA256
- RSASSA-PKCS1-v1_5 + SHA256
- ECDSA + P-256 + SHA256
- RSA vs ECDSA
- 同等安全度下
- RSA 更长, 签名验证更快
- ECDSA 更短, 生成签名和密钥时快得多
 
 
- 同等安全度下
- 参考
示例
{
  "iss": "http://example.org",
  "aud": "http://example.com",
  "iat": 1356999524,
  "nbf": 1357000000
}
{
  "iss": "https://oidc.my.com",
  "x5t": "AAAAAAAAAAAAAAAAAAAA"
  "typ": "JWT"
  "alg": "RS265"
}
{
  "sub": "wener"
  "name": "Wener"
  "email": "[email protected]"
  "phone_number": "1852159826715"
  "aud": "https://otheremail.com"
  "iss": "https://oidc.my.com"
  "nbf": 1497868409096
  "jti": "ANpzy7AyyANx0Cn8WMP5N7bG3E8awOhB"
  "exp": 1497868509096
  "nbf": 1497868409096
}
JWKS
https://www.googleapis.com/service_accounts/v1/jwk/[email protected]
https://auth0.com/docs/tokens/reference/jwt/jwks-properties
https://sandrino.auth0.com/.well-known/jwks.json https://sandrino.auth0.com/pem
https://docs.hasura.io/1.0/graphql/manual/auth/authentication/jwt.html
{
  "keys": [
    {
      "alg": "RS256",
      "kty": "RSA",
      "use": "sig",
      "n": "",
      "e": "AQAB",
      "kid": "RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg",
      "x5t": "RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg",
      "x5c": [
        // base64 编码
        ""
      ]
    }
  ]
}
https://developers.google.com/identity/protocols/OpenIDConnect
{
  "keys": [
    {
      "e": "AQAB",
      "kty": "RSA",
      "alg": "RS256",
      "n": "1Zi0-4bNwZ7gGefz17U2NoKT4xBq-nzAa899teHxB2Q9KVCZYDhbQkpiIrBNg2u8s6TtoSljpq6MJpsKJVJgpT70gDCCgaUsGNYql9-kwWNKd80FlU1sjDEGouUIVEoYHzooPyn9r027KzMnTv5LGRYjxb5lvGnb4UCw5MF_EeSTNpGD7zb0b6juXwBxPi0oIUbQxAcGgH3oS40hXAjJ_U2T3Hln8lBlnVhLbrh-5qF-uoYDxjtAY9XyEJQH_rGiRfXWgBfSM02t9DCB46sQbEMM2iLe7mkGrZtCHR4zbAsAP0s2VGqSmwszNTWqqsdOccbfXp3i_ThkR3pDdTSIQQ",
      "use": "sig",
      "kid": "57b1928f2f63329f2e92f4f278f94ee1038c923c"
    },
    {
      "e": "AQAB",
      "kty": "RSA",
      "alg": "RS256",
      "n": "rEpSQ8IO8Gauj5AGRbgfwfaxHRMGONuTog4fWKWzZYxdWa76khbynWTAzUJVzw_FaAiZGnl7tlmD7pdKWOHszrcK2Hru87KzeRnnqvWlSqdKValu6x5TfBnJwxgr-L8Mnu4xNnrMG2AWcRkjFVWQmwZyEF3WroRzbxrVTlChD_UydnRuiV1z0BPkLOxTzF5RH21ukImElOm3AFIFXP5h8Z0yLrFEcxzLgDIt7wC68apH7uRmy2-a9D4b4Jwi3HRlAgsYAKXYeEQC3f8Mv03liJBv3CPZU4EyXLQUJA28b8l5NUSDI9tnbrfP8SIXlqLz8mNfuKR18LAU3s9sv-sR3Q",
      "use": "sig",
      "kid": "47456b8069e4365e517ca5e29757d1a9efa567ba"
    }
  ]
}