`

Json Web Token(JWT)简介

 
阅读更多

在JavaScript前端技术大行其道的今天,我们通常只需在后台构建API提供给前端调用,并且后端仅仅设计为给前端移动App调用。用户认证是Web应用的重要组成部分,基于API的用户认证有两个最佳解决方案 —— OAuth 2.0 和JWTJSON Web Token)。

JWT的主要应用场景:

  • 身份认证
    在这种场景下,一旦用户完成了登陆,在接下来的每个请求中包含JWT,可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。由于它的开销非常小,可以轻松的在不同域名的系统中传递,所有目前在单点登录(SSO)中比较广泛的使用了该技术。

  • 信息交换
    在通信的双方之间使用JWT对数据进行编码是一种非常安全的方式,由于它的信息是经过签名的,可以确保发送者发送的信息是没有经过伪造的。

1、JWT定义及其组成

       JWT(JSON Web Token)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。

      Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

载荷(Payload)

我们先将用户认证的操作描述成一个JSON对象。其中添加了一些其他的信息,帮助今后收到这个JWT的服务器理解这个JWT。

{
    "sub": "1",
    "iss": "http://localhost:8000/auth/login",
    "iat": 1451888119,
    "exp": 1454516119,
    "nbf": 1451888119,
    "jti": "37c107e4609ddbcc9c096ea5ee76c667"
}

这里面的前6个字段都是由JWT的标准所定义的。

  • sub: 该JWT所面向的用户
  • iss: 该JWT的签发者
  • iat(issued at): 在什么时候签发的token
  • exp(expires): token什么时候过期
  • nbf(not before):token在此时间之前不能被接收处理
  • jti:JWT ID为web token提供唯一标识

这些定义都可以在标准中找到。

将上面的JSON对象进行base64编码可以得到下面的字符串:

eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWx
ob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDUxODg4MTE5LCJleHAiOjE0NTQ1MTYxMTksIm5iZiI6MTQ1MTg4OD
ExOSwianRpIjoiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjcifQ

这个字符串我们将它称作JWT的Payload(载荷)。

如果你使用Node.js,可以用Node.js的包base64url来得到这个字符串:

var base64url = require('base64url')
var header = {
    "from_user": "B",
    "target_user": "A"
}
console.log(base64url(JSON.stringify(header)))

注:Base64是一种编码,也就是说,它是可以被翻译回原来的样子来的。它并不是一种加密过程。

头部(Header)

JWT还需要一个头部,头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。这也可以被表示成一个JSON对象:

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

在这里,我们说明了这是一个JWT,并且我们所用的签名算法(后面会提到)是HS256算法。

对它也要进行Base64编码,之后的字符串就成了JWT的Header(头部):

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

签名(签名)

将上面的两个编码后的字符串都用句号.连接在一起(头部在前),就形成了:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWx
ob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDUxODg4MTE5LCJleHAiOjE0NTQ1MTYxMTksIm5iZiI6MTQ1MTg4OD
ExOSwianRpIjoiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjcifQ

最后,我们将上面拼接完的字符串用HS256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret):

HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret
)

这样就可以得到我们加密后的内容:

wyoQ95RjAyQ2FF3aj8EvCSaUmeP0KUqcCJDENNfnaT4

这一部分又叫做签名。

最后将这一部分签名也拼接在被签名的字符串后面,我们就得到了完整的JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWx
ob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDUxODg4MTE5LCJleHAiOjE0NTQ1MTYxMTksIm5iZiI6MTQ1MTg4OD
ExOSwianRpIjoiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjcifQ.wyoQ95RjAyQ2FF3aj8EvCSaUmeP0KUqcCJDENNfnaT4

JTI和replay attack

重放攻击(Replay Attacks)又称重播攻击、回放攻击或新鲜性攻击(Freshness Attacks),是指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。 
jti是被放到JWT中的唯一的ID,可以防止重放攻击。

 

使用场景

最常见的使用场景是用作 身份认证(Authentication, Web 和 Mobile 皆可),还可以用作 组件间传递安全信息的载体

组成

一个 JWT 由三个部分组成:Header, Playload, Signature:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 1. Headers
// alg: 加密算法,比如 HMAC SHA256 或 RSA
// typ: toke 的类型
{
  "alg": "HS256",
  "typ": "JWT"
}

// 2. Payload
// 用户信息
// sub:常指用户 ID
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

// 3. Signature
// 服务端可以通过签名保证 JWT 并未被恶意修改,简单来说就是确认是否合法
// 如代码所示,利用 header 中声明的算法来生成,通常会在服务端指定一个 SECRET KEY,保证后期的安全校验
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  SECRET_KEY)

最后,服务端通过 点号(.) 拼接三个部分生成一个可以发往客户端的 JWT:

1
2
3
base64UrlEncode(header) + '.' + base64UrlEncode(payload) + signature

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

如何使用JWT?

在身份鉴定的实现中,传统方法是在服务端存储一个session,给客户端返回一个cookie,而使用JWT之后,当用户使用它的认证信息登陆系统之后,会返回给用户一个JWT,用户只需要本地保存该token(通常使用local storage,也可以使用cookie)即可。

当用户希望访问一个受保护的路由或者资源的时候,通常应该在Authorization头部使用Bearer模式添加JWT,其内容看起来是下面这样:

Authorization: Bearer <token>

因为用户的状态在服务端的内存中是不存储的,所以这是一种无状态的认证机制。服务端的保护路由将会检查请求头Authorization中的JWT信息,如果合法,则允许用户的行为。由于JWT是自包含的,因此减少了需要查询数据库的需要。

JWT的这些特性使得我们可以完全依赖其无状态的特性提供数据API服务,甚至是创建一个下载流服务。因为JWT并不使用Cookie的,所以你可以使用任何域名提供你的API服务而不需要担心跨域资源共享问题(CORS)。

原理

官网的一张图很清晰地说明了整个交互的过程:

  1. 浏览器用用户名和密码发起登录请求
  2. 服务端验证后产生一个 JWT 返回
  3. 浏览器需要保存 token(HTML5 的 localStorage sessionStoreage 或者传统的 cookie),服务端不需要保存
  4. 浏览器在请求需要验证的资源时都需要带上 jwt,通常是在 HTTP header 中设置:Authorization: Bearer <token>

jwt-process

JWT 的优势

JWT 对比 基于 cookie 验证方式的优点(这篇文章写得很详细,以下简单罗列一下):

  1. Cross-domain / CORS: 可以对任何 server 发起 AJAX 请求 2. Stateless (a.k.a. Server side scalability): 服务端无需保存 token,扩展方便
  2. CDN: 可以把资源文件都放在 CDN 上,服务端其实只是提供 API
  3. Mobile ready: 移动端处理 jwt 比 cookie 容易多了
  4. CSRF: 没有 cookie
  5. Performance: 解密(HMACSHA256)比找session应该块多了
  6. Standard-based: RFC标准,语言库支持丰富,大厂(比如 FirebaseGoogle)使用
  7. Decoupling(架构去耦): 不需要绑定特定的身份验证方案

深入学习的一些资料

  1. 10 Things you should know about Tokens (亲切的中文翻译)
  2. Token based authentication in realtime frameworks like Socket.io
  3. JWT Authentication with AngularJS – Video and Tutorial
  4. 主要讲安全的 Cookies are bad for you: Improving web application security
分享到:
评论

相关推荐

    c# JSON WEB TOKEN JWT.dll

    生成token工具,webapi 接口 token JWT的Web API身份验证Json Web Token(jwt)是一种不错的身份验证及授权方案,简单的说就是调用端调用api时,附带上一个由api端颁发的token,以此来验证调用者的授权信息。

    php实现JWT(json web token)鉴权实例详解

    JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。基于token的身份验证可以替代传统的cookie+session身份验证方法...

    JWT(json web token)包

    JWT(json web token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。 JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上...

    JWT(JSON Web Token):JWT简介与原理.docx

    JWT(JSON Web Token):JWT简介与原理.docx

    单点登录中的JSON WEB TOKEN的使用方法C#版

    Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。本实例还原了整个的使用流程。建议...

    Json Web Token(JWT)介绍与基本使用详解及完整源码示例

    Json Web Token(JWT)是一种轻量级的身份验证和授权机制,广泛应用于Web应用程序,特别是单页应用(SPA)和微服务架构中。JWT通过在客户端和服务器之间传递JSON编码的信息来实现用户认证,无需在服务器端存储会话...

    JWT(JSON Web Token):JWT的常见问题与解决方案.docx

    JWT(JSON Web Token):JWT的常见问题与解决方案.docx

    JWT-JSON Web Token實作分享1

    JSON Web Token(JWT)是一种基于 token 的身份验证机制,它可以提供一种无状态、可扩展、安全的身份验证方式。下面将详细介绍 JWT 的实现和使用。 为什么需要 Web Token? 在服务器端身份验证中,传统的基于...

    JWT(JSON Web Token):JWT签名算法详解.docx

    JWT(JSON Web Token):JWT签名算法详解.docx

    JWT(JSON Web Token):JWT的安全性分析与最佳实践.docx

    JWT(JSON Web Token):JWT的安全性分析与最佳实践.docx

    JWT(json web token加密算法) for C# dll 文件,亲测可用

    JSON Web Token(JWT)是一种开放的标准(RFC 7519),定义了一种紧凑的、自包含的方式来安全地在各方之间传输信息作为一个JSON对象。这个信息可以被验证和信任,因为它是数字签名的。JWT可用于身份验证、授权,以及...

    ASP.NET WebAPI Token JWT Bearer 认证失败和成功返回自定义数据 Json

    asp.net WebAPI Token Oauth2.0授权自定义返回结果(包括登录正确返回,登录失败返回)。 详细参考:https://blog.csdn.net/u013546115/article/details/105580532

    JWT(Json Web Token)Java实现jar

    JSON Web Token(JWT)是一种广泛使用的轻量级身份验证和授权机制,主要应用于Web应用程序和服务之间的安全通信。JWT通过在客户端和服务器之间传递令牌来携带信息,这些信息经过签名,可以确保数据的完整性和不可...

    JSON Web Token (JWT)的简单介绍、验证过程及令牌刷新思路

    Jwt验证过程导入到项目中的util包下。

    web api JWT token认证

    1. **JWT Token简介** JSON Web Token由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。头部和载荷被编码为Base64字符串,签名则是通过一个密钥(secret key)和前两部分进行哈希运算得到,用于...

    JWT Token生成及验证

    JSON Web Token(JWT)是一种开放的标准(RFC 7519),定义了一种紧凑的、自包含的方式来安全地在各方之间传输信息作为JSON对象。这种信息可以被验证和信任,因为它是数字签名的。JWT在身份验证和授权场景中广泛应用...

    Json Web Token 介绍与基本使用完整源码

    Json Web Token(JWT)是一种轻量级的身份验证和授权机制,广泛应用于Web应用程序,特别是单页应用(SPA)和微服务架构中。JWT通过在客户端和服务器之间传递JSON编码的信息来实现用户认证,无需在服务器端存储会话...

    .Net WebAPi JWT身份验证

    JSON Web Token(JWT)是一种轻量级的身份验证和授权机制,被广泛应用于API访问控制。本文将深入探讨如何在.NET Framework 4.6.2的WebAPI项目中实现JWT身份验证。 首先,理解JWT的基础概念。JWT是一个自包含的令牌...

    JWT-Json Web Token-目前最流行跨域身份验证解决方案

    JWT是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,...

Global site tag (gtag.js) - Google Analytics