`

JSON Web Token - 在Web应用间安全地传递信息

 
阅读更多

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

让我们来假想一下一个场景。在A用户关注了B用户的时候,系统发邮件给B用户,并且附有一个链接“点此关注A用户”。链接的地址可以是这样的

1
https://your.awesome-app.com/make-friend/?from_user=B&target_user=A

上面的URL主要通过URL来描述这个当然这样做有一个弊端,那就是要求用户B用户是一定要先登录的。可不可以简化这个流程,让B用户不用登录就可以完成这个操作。JWT就允许我们做到这点。

JSON Web Token

JWT的组成

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

载荷(Payload)

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

1
2
3
4
5
6
7
8
9
{
"iss": "John Wu JWT",
"iat": 1441593502,
"exp": 1441594722,
"aud": "www.example.com",
"sub": "jrocket@example.com",
"from_user": "B",
"target_user": "A"
}

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

  • iss: 该JWT的签发者
  • sub: 该JWT所面向的用户
  • aud: 接收该JWT的一方
  • exp(expires): 什么时候过期,这里是一个Unix时间戳
  • iat(issued at): 在什么时候签发的

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

将上面的JSON对象进行[base64编码]可以得到下面的字符串。这个字符串我们将它称作JWT的Payload(载荷)。

1
eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9

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

1
2
3
4
5
6
7
var base64url = require('base64url')
var header = {
"from_user": "B",
"target_user": "A"
}
console.log(base64url(JSON.stringify(header)))
// 输出:eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9

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

头部(Header)

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

1
2
3
4
{
"typ": "JWT",
"alg": "HS256"
}

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

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

1
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
签名(签名)

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

1
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0

这一部分的过程在node-jws的源码中有体现

最后,我们将上面拼接完的字符串用HS256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret)。如果我们用mystar作为密钥的话,那么就可以得到我们加密后的内容

1
rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

这一部分又叫做签名

签名过程

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

1
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

于是,我们就可以将邮件中的URL改成

1
https://your.awesome-app.com/make-friend/?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

这样就可以安全地完成添加好友的操作了!

且慢,我们一定会有一些问题:

  1. 签名的目的是什么?
  2. Base64是一种编码,是可逆的,那么我的信息不就被暴露了吗?

让我逐一为你说明。

签名的目的

最后一步签名的过程,实际上是对头部以及载荷内容进行签名。一般而言,加密算法对于不同的输入产生的输出总是不一样的。对于两个不同的输入,产生同样的输出的概率极其地小(有可能比我成世界首富的概率还小)。所以,我们就把“不一样的输入产生不一样的输出”当做必然事件来看待吧。

所以,如果有人对头部以及载荷的内容解码之后进行修改,再进行编码的话,那么新的头部和载荷的签名和之前的签名就将是不一样的。而且,如果不知道服务器加密的时候用的密钥的话,得出来的签名也一定会是不一样的。

签名过程

服务器应用在接受到JWT后,会首先对头部和载荷的内容用同一算法再次签名。那么服务器应用是怎么知道我们用的是哪一种算法呢?别忘了,我们在JWT的头部中已经用alg字段指明了我们的加密算法了。

如果服务器应用对头部和载荷再次以同样方法签名之后发现,自己计算出来的签名和接受到的签名不一样,那么就说明这个Token的内容被别人动过的,我们应该拒绝这个Token,返回一个HTTP 401 Unauthorized响应。

信息会暴露?

是的。

所以,在JWT中,不应该在载荷里面加入任何敏感的数据。在上面的例子中,我们传输的是用户的User ID。这个值实际上不是什么敏感内容,一般情况下被知道也是安全的。

但是像密码这样的内容就不能被放在JWT中了。如果将用户的密码放在了JWT中,那么怀有恶意的第三方通过Base64解码就能很快地知道你的密码了。

JWT的适用场景

我们可以看到,JWT适合用于向Web应用传递一些非敏感信息。例如在上面提到的完成加好友的操作,还有诸如下订单的操作等等。

其实JWT还经常用于设计用户认证和授权系统,甚至实现Web应用的单点登录。在下一次的文章中,我将为大家系统地总结JWT在用户认证和授权上的应用。如果想要及时地收到下一篇文章的更新,您可以在下方订阅我的半月刊:)

分享到:
评论

相关推荐

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

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

    JWT(json web token)包

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

    JWT(Json Web Token)Java实现jar

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

    单点登录中的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加密算法) for C# dll 文件,亲测可用

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

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

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

    WebApi 使用TOKEN+签名验证

    在Web开发中,API的安全性至关重要,特别是对于公开暴露的WebApi接口,它们通常处理敏感数据和业务逻辑。"WebApi使用TOKEN+签名验证"是一种常见的安全策略,它结合了令牌(Token)验证和签名机制,以确保只有授权的...

    C#WEB用户令牌TOKEN验证防止HTTPGETPOST等提交

    - JWT:JWT是一种轻量级的身份验证协议,它允许用户在多个服务间安全地传递信息,无需进行服务器之间的状态维护。JWT由三部分组成:头部、负载和签名,每个部分都是经过Base64编码的字符串。 2. **防止...

    js代码-JWT(json-web-token)-认识与学习

    JSON Web Token (JWT) 是一种安全的身份验证和授权机制,常用于Web应用中实现状态less的用户认证。JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature),这三部分通过Base64编码后用点(.)分隔。...

    sa-token封装了一下

    它可能是JWT(JSON Web Token)或者其他自定义格式,包含用户的标识和其他元数据,确保安全的用户交互。 【压缩包子文件的文件名称列表】: 1. mvnw.cmd:这是Spring Boot项目的命令行启动脚本,用于在Windows环境...

    基于.net语言的web token

    Web Token的出现解决了这些问题,它将用户的身份信息编码为一个字符串,这个字符串可以在客户端和服务器之间安全地传递,用于验证用户的身份。JWT(JSON Web Tokens)是Web Token的一种标准格式,包含了发行者、受众...

    第38天:WEB漏洞-反序列化之PHP&JAVA全解(下)1

    0x02部分,通过登录接口的响应数据,可以看到返回的JWT(JSON Web Token)中可能包含了Java序列化数据。这段数据以“rO0AB”开头,表明它可能是Java的序列化数据。通过Python脚本解码并利用SerializationDumper工具...

    json-web-token:jwt与基于会话的身份验证

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

    详解JSON Web Token 入门教程

    JSON Web Token(JWT)是网络上广泛使用的跨域认证解决方案。...总之,JSON Web Token为解决跨域认证问题提供了高效的方案,其轻量级、跨域兼容、安全性高等特点,使其在现代Web应用开发中变得尤为重要。

    手把手教你AspNetCore WebApi认证与授权的方法

    前言 这几天小明又有烦恼了,之前给小红的接口没有做认证授权,直接裸奔在线上,被马老板发现后...Json web token (JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧

    Webapi_JWT_Authentication-master_webapi_jwt_token_

    JWT令牌提供了一种轻量级的方式来进行身份验证和授权,它允许服务器在客户端之间安全地传递信息,而无需存储会话状态。在本项目"Webapi_JWT_Authentication-master"中,我们将探讨如何实现这一机制。 首先,WebAPI...

    JWT(java web Token)

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

    rest-api-nodejs-jwt-express-mysql:这是一个使用NodeJS,Express,MySQL并使用JSON-web-token作为身份验证的国家的小型REST Api

    4. **JSON Web Token (JWT) 身份验证**: JWT是一种轻量级的身份验证标准,通过在客户端和服务器之间传递令牌来验证用户身份。在登录成功后,服务器会生成一个包含用户信息的JWT,并发送给客户端。客户端在后续的请求...

    03-后台用户登录-Token模块-已解锁

    JWT是一种开放标准(RFC 7519),它定义了一种自包含的、紧凑的数据结构,可用于以JSON对象的形式安全地在各方之间传输信息。JWT主要由三部分组成:头部(Header)、负载(Payload)和签名(Signature)。JWT的这种...

Global site tag (gtag.js) - Google Analytics