手机端接口开发会遇到一个问题是,接口登录后需要返回一个Token。token首先有一点必须唯一,每次请求都需要把token给带上。基于必须唯一的特性,很多朋友在开发是都选择了uuid。是不是token的生成有没有可以遵循的标准,或生成token的一些技术呢?

本文将介绍生成token标记JSON Web Token(TWT)

什么是JSON Web令牌?

JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为JSON对象传输。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSAECDSA的公用/专用密钥对对JWT进行签名

尽管可以对JWT进行加密以在各方之间提供保密性,但我们将重点关注已签名的令牌。签名的令牌可以验证其中包含的声明的完整性,而加密的令牌则将这些声明隐藏在其他方的面前。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是对其进行签名的一方。

什么时候应该使用JSON Web令牌?

以下是JSON Web令牌有用的一些情况:

  • 授权:这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。

  • 信息交换:JSON Web令牌是在各方之间安全地传输信息的好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确定发件人是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否遭到篡改。

JSON Web令牌结构是什么?

JSON Web令牌以紧凑的形式由三部分组成,这些部分由点(.)分隔,分别是:

  • 标头
  • 有效载荷
  • 签名

因此,JWT通常如下所示。

xxxxx.yyyyy.zzzzz

让我们分解不同的部分。

标头

标头通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法,例如HMAC SHA256或RSA。

例如:

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

然后,此JSON被Base64Url编码以形成JWT的第一部分。

有效载荷

令牌的第二部分是有效负载,其中包含声明。声明是有关实体(通常是用户)和其他数据的声明。索赔有以下三种类型:注册的公共的私人索赔。

令牌的第二部分是有效负载,其中包含声明。声明是有关实体(通常是用户)和其他数据的声明。索赔有以下三种类型:注册的公共的私人索赔。

  • 已注册的权利要求:这些是一组非强制性的但建议使用的预定义权利要求,以提供一组有用的,可互操作的权利要求。其中一些是: iss(发布者), exp(到期时间), sub(主题), aud(受众群体)

    请注意,声明名称仅是三个字符,因为JWT是紧凑的。

  • 公开声明:使用JWT的人员可以随意定义这些声明。但是为避免冲突,应在IANA JSON Web令牌注册表中定义它们,或将其定义为包含抗冲突名称空间的URI。

  • 私人权利:这些都是使用它们同意并既不是当事人之间建立共享信息的自定义声明注册公众的权利要求。

有效负载示例可能是:

{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

然后,对有效负载进行Base64Url编码,以形成JSON Web令牌的第二部分。

请注意,对于已签名的令牌,此信息尽管可以防止篡改,但任何人都可以读取。除非将其加密,否则请勿将机密信息放入JWT的有效负载或报头元素中。

签名

要创建签名部分,您必须获取编码的标头,编码的有效载荷,机密,标头中指定的算法,并对其进行签名。

例如,如果要使用HMAC SHA256算法,则将通过以下方式创建签名:

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

签名用于验证消息在此过程中没有更改,并且对于使用私钥进行签名的令牌,它还可以验证JWT的发送者是它所说的真实身份。

放在一起

输出是三个由点分隔的Base64-URL字符串,可以在HTML和HTTP环境中轻松传递这些字符串,与基于XML的标准(例如SAML)相比,它更紧凑。

下面显示了一个JWT,它已对先前的标头和有效负载进行了编码,并用一个秘密进行了签名。

如果您想使用JWT并将这些概念付诸实践,则可以使用jwt.io Debugger解码,验证和生成JWT。

JSON Web令牌如何工作?

在身份验证中,当用户使用其凭据成功登录时,将返回JSON Web令牌。由于令牌是凭据,因此必须格外小心以防止安全问题。通常,令牌的保留时间不应超过要求的时间。

由于缺乏安全性,您也不应该将敏感的会话数据存储在浏览器中

每当用户想要访问受保护的路由或资源时,用户代理通常应使用承载模式在授权标头中发送JWT 。标头的内容应如下所示:

Authorization: Bearer <token>

在某些情况下,这可以是无状态授权机制。服务器的受保护路由将在Authorization标头中检查有效的JWT ,如果存在,则将允许用户访问受保护的资源。如果JWT包含必要的数据,则可以减少查询数据库中某些操作的需求,尽管这种情况并非总是如此。

如果令牌是在Authorization标头中发送的,则跨域资源共享(CORS)不会成为问题,因为它不使用cookie。

下图显示了如何获取JWT并将其用于访问API或资源:

  1. 应用程序或客户端向授权服务器请求授权。这是通过不同的授权流程之一执行的。例如,典型的符合OpenID Connect的 Web应用程序将/oauth/authorize使用授权代码流通过端点。
  2. 授予授权后,授权服务器会将访问令牌返回给应用程序。
  3. 该应用程序使用访问令牌来访问受保护的资源(例如API)。

请注意,使用签名的令牌,令牌中包含的所有信息都会暴露给用户或其他方,即使他们无法更改它。这意味着您不应将机密信息放入令牌中。

我们为什么要使用JSON Web令牌?

让我们谈谈与简单Web令牌(SWT)安全性声明标记语言令牌(SAML)相比,JSON Web令牌(JWT)的好处。

由于JSON不如XML冗长,因此在编码时JSON的大小也较小,从而使JWT比SAML更为紧凑。这使得JWT是在HTML和HTTP环境中传递的不错的选择。

在安全方面,只能使用HMAC算法由共享机密对SWT进行对称签名。但是,JWT和SAML令牌可以使用X.509证书形式的公用/专用密钥对进行签名。与签名JSON的简单性相比,使用XML数字签名对XML进行签名而不引入模糊的安全漏洞是非常困难的。

JSON解析器在大多数编程语言中都很常见,因为它们直接映射到对象。相反,XML没有自然的文档到对象映射。与SAML断言相比,这使使用JWT更加容易。

关于用法,JWT是在Internet规模上使用的。这强调了在多个平台(尤其是移动平台)上对JSON Web令牌进行客户端处理的简便性。

编码的JWT和编码的SAML的长度比较

如果您想了解有关JSON Web令牌的更多信息,甚至开始使用它们在自己的应用程序中执行身份验证,请浏览到Auth0 上的JSON Web令牌登录页面

Java中使用JSON Web令牌

GitHub源码:https://github.com/auth0/java-jwt

Maven中导入jwt包:

<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.0</version>
</dependency>

通过secret创建token,以下代码是通过HMAC256加密算法进行处理,也可以使用其他算法进行加密处理,可支持的算法如下。

    /**
* 创建token
* 可以设置如下内容: iss(发布者), exp(到期时间), sub(主题), aud(受众群体)
* @return
*/
public String createTokenByHMAC256(){
try {
Algorithm algorithmHS = Algorithm.HMAC256(secret);
JWTCreator.Builder builder = JWT.create();
if(StringUtils.isNotEmpty(iss)){
builder.withIssuer(iss);
}
if(StringUtils.isNotEmpty(sub)){
builder.withSubject(sub);
}
if(exp!=null){
builder.withExpiresAt(exp);
}
String token = builder.sign(algorithmHS);
return token;
} catch (JWTCreationException exception){
//Invalid Signing configuration / Couldn't convert Claims.
}
return null;
}

Token校验

    /**
* 校验Token的正确性
* @param token
* @return
*/
public boolean verify(String token){
try {
Algorithm algorithm = Algorithm.HMAC256("secret");
Verification require = JWT.require(algorithm);
if(StringUtils.isNotEmpty(iss)){
require.withIssuer(iss);
}
if(StringUtils.isNotEmpty(sub)){
require.withSubject(sub);
}
JWTVerifier verifier = require
.build(); //Reusable verifier instance
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (JWTVerificationException exception){
//Invalid signature/claims
return false;
}
}

解码令牌

   /**
* 解码token
* @param token
* @return
*/
public DecodedJWT decode(String token){
try {
DecodedJWT jwt = JWT.decode(token);
return jwt;
} catch (JWTDecodeException exception){
//Invalid token
}
return null;
}

JSON Web令牌(JWT)介绍与使用的更多相关文章

  1. 了解JSON Web令牌(JWT)

    JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案. (一) 跨域身份验证 Internet服务无法与用户身份验证分开. 用户向服务器发送用户名和密码. 验证服务器后,相关数据( ...

  2. 简单了解JSON Web令牌(JWT)

    什么是JWT JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该信息可以被验证和信任,因为它 ...

  3. JSON WEB Token(JWT)

    最近面试被问及单点登陆怎么解决?自己的项目前后端分离,自己实现token认证,token有失效时间,token中包含用户基本的信息.且一个当用户重新登陆后,原来的token就会失效,这么安全的一个to ...

  4. JSON Web Token (JWT) 实现与使用方法

    1. JSON Web Token是什么 JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该 ...

  5. Json Web Token(JWT)详解

    什么是Json Web Token Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的 ...

  6. JSON Web Token (JWT) - Introduction

    To validate the challenge, connect as admin.------------以admin登陆 https://jwt.io/introduction/        ...

  7. JSON Web Token (JWT),服务端信息传输安全解决方案。

    JWT介绍 JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑独立的基于JSON对象在各方之间安全地传输信息的方式.这些信息可以被验证和信任,因为它是数字签名的 ...

  8. JSON Web Token (JWT) 简介

    JSON Web Token (JWT) 是一种基于 token 的认证方案. JSON Web Token 的结构 一个 JWT token 看起来是这样的: eyJhbGciOiJIUzI1NiI ...

  9. 10分钟了解JSON Web令牌(JWT)

    JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案.虫虫今天给大家介绍JWT的原理和用法. 1.跨域身份验证 Internet服务无法与用户身份验证分开.一般过程如下. 1.用户 ...

随机推荐

  1. Python 为什么不用分号作终止符?

    一般而言,编程语言中使用分号";"来实现两种目的: 作为语句分隔符:使用分号来分隔语句(statement),这样就能在一行代码中书写多条语句(一行多句) 作为语句终止符:使用分号 ...

  2. 【转】shell的反引号、单引号、双引号的作用

    Linux Shell中有三种引号,分别为双引号(" ").单引号(' ')以及反引号(` `). 其中双引号对字符串中出现的$.''.`和\进行替换:单引号不进行替换,将字符串中 ...

  3. windows下grunt的快速入门

    1.认识grunt  grunt是什么:他是一套前端自动化工具,是一个基于nodejs的命令行工具.(Grunt和Grunt插件是通过npm  安装并管理的,所以首先要安装nodejs). grunt ...

  4. 关于hexo-blog-encrypt插件输入密码后无响应的问题

    解决方案:更改网站为https协议 具体请查看: https://github.com/MikeCoder/hexo-blog-encrypt/issues/114

  5. Java实现 蓝桥杯 算法提高 进攻策略加强(暴力)

    试题 算法提高 进攻策略加强 问题描述 植物大战僵尸这款游戏中,还有一个特别的玩儿法:玩家操纵僵尸进攻植物. 首先,僵尸有m种(每种僵尸都是无限多的),玩家可以选择合适的僵尸来进攻.使用第i种僵尸需要 ...

  6. Java实现 LeetCode 756 金字塔转换矩阵(DFS)

    756. 金字塔转换矩阵 现在,我们用一些方块来堆砌一个金字塔. 每个方块用仅包含一个字母的字符串表示. 使用三元组表示金字塔的堆砌规则如下: 对于三元组(A, B, C) ,"C" ...

  7. Java实现 LeetCode 300 最长上升子序列

    300. 最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,10 ...

  8. Java实现 蓝桥杯VIP 算法提高 连接乘积

    算法提高 连接乘积 时间限制:1.0s 内存限制:256.0MB 问题描述 192这个数很厉害,用它分别乘以1.2.3,会得到: 192 x 1 = 192 192 x 2 = 384 192 x 3 ...

  9. Java实现 LeetCode 10 正则表达式匹配

    10. 正则表达式匹配 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符 '*' 匹配零个或多个前面的那一个元素 所谓匹配, ...

  10. Java实现蓝桥杯有歧义的号码

    描述 小Hi参加了一场大型马拉松运动会,他突然发现面前有一位参赛者背后的号码竟然和自己一样,也是666.仔细一看,原来那位参赛者把自己号码帖反(旋转180度)了,结果号码999看上去变成了号码666. ...