浅谈json web token及应用
Json Web Token (JWT),是一个非常轻巧的规范,这个规范允许在网络应用环境间客户端和服务器间较安全的传递信息。该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。

在web应用中,我们提供的API接口,通过GET或者POST方式调用,在调用过程中,就存在着接口认证及数据的安全性问题。例如如下问题:
1、请求来自哪里,身份是否合法?
2、请求参数是否被篡改?
3、客户端请求的唯一性,是否为重复请求攻击(RepeatAttack)?
传统的Session认证方式
在传统的web应用中,服务端成功相应请求者,返回正常的response依赖于服务端通过一种存储机制把每个用户经过认证之后的会话信息(session)记录服务器端,一般记录到内存、磁盘、数据库中,这种方式在请求量和用户量增多的时候无疑会增大服务端的开销;如果是记录在内存中,那每次请求都分发登到该机器上才能授权获取资源,那在分布式系统中就存在着问题;因为是基于Cookie的,如果Cookie被截获,攻击者会盗用身份信息进行发送恶意请求,也就是“跨站请求伪造”(CSRF)。
基于token的认证方式
客户端用用户名和密码经过服务器认证之后,服务器会签发一个token返回给客户端,客户端存储token(一般存在请求头里),并且在之后的请求里附带此token,服务器每次会解签名token,验证通过则返回资源。另外服务端要支持CORS跨来源资源共享)策略,服务器处理完请求之后,会再返回结果中加上Access-Control-Allow-Origin。
jwt的生成
token是接口的令牌,好比去衙门办事,“衙门口朝南开,有理无钱莫进来”。没有令牌就别想办事。token的验证方法很多,也生成了很多标准,jwt就是一种基于json的RFC 7519。该标准由三部分组成:
header
payload
signature
header和payload经过base64编码后用点拼接起来。signature是把header和payload编码和拼接后经过加密算法加密,加密时还要一个密码,这个密码保存在服务器端。大致示意图如下:

Header:
head由两部分组成,一个是token类型,一个是使用的算法,如下类型为jwt,使用的算法是HS256。当然,还有HS384、HS512算法。
{
"typ": "JWT",
"alg": "HS256"
}
将以上json进行base64编码,当然编码前将json去格式化,如图:

生成的编码为:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
用go语言实现:
package main
import (
"fmt"
"encoding/base64"
)
func main() {
head1 := `{"typ":"JWT","alg":"HS256"}`
fmt.Println(base64.StdEncoding.EncodeToString([]byte(head1)))
}
Payload:
payload 里面是 token 的具体内容,这些内容里面有一些是标准字段,我们也可以添加自定义内容。如下:
{
"iss": "smallsoup",
"iat": 1528902195,
"exp": 1528988638,
"aud": "www.smallsoup.com",
"sub": "smallsoup@qq.com",
"userId": "0418"
}
这里面的前五个字段都是由JWT的标准所定义的,在jwt标准中都可以找到。
iss: 该JWT的签发者
sub: 该JWT所面向的用户
aud: 接收该JWT的一方
exp(expires): 什么时候过期,这里是一个Unix时间戳
iat(issued at): 在什么时候签发的
最后一个userId表示了用户信息,为自定义字段,我们也可以定义角色等其他字段。以上的json去格式化后的base64编码如下:
eyJpc3MiOiJzbWFsbHNvdXAiLCJpYXQiOjE1Mjg5MDIxOTUsImV4cCI6MTUyODk4ODYzOCwiYXVkIjoid3d3LnNtYWxsc291cC5jb20iLCJzdWIiOiJzbWFsbHNvdXBAcXEuY29tIiwidXNlcklkIjoiMDQxOCJ9

Signature:
JWT 的最后一部分是 Signature ,这部分内容有三个部分,先是用 Base64 编码的 header.payload ,再用加密算法加密一下,加密的时候要放进去一个 Secret ,这个相当于是一个密码,这个密码秘密地存储在服务端。
header
payload
secret
假设这里secret为mysecret,则用go语言实现代码如下:
package main
import (
"fmt"
"encoding/base64"
"crypto/hmac"
"crypto/sha256"
"strings"
)
func main() {
head1 := `{"typ":"JWT","alg":"HS256"}`
head1Base64 := base64.StdEncoding.EncodeToString([]byte(head1))
payload1 := `{"iss":"smallsoup","iat":1528902195,"exp":1528988638,"aud":"www.smallsoup.com","sub":"smallsoup@qq.com","userId":"0418"}`
payload1Base64 := base64.StdEncoding.EncodeToString([]byte(payload1))
encodedstring := head1Base64 + "." + payload1Base64
hash := hmac.New(sha256.New, []byte("mysecret"))
hash.Write([]byte(encodedstring))
signature := strings.TrimRight(base64.URLEncoding.EncodeToString(hash.Sum(nil)), "=")
fmt.Printf(signature)
}
运行结果为:
fjjbA93FTcE71hz_cyIzCUFYdTdyl9hA0w7Pa0ltduc
最后这个在服务端生成并且要发送给客户端的 Token 看起来像这样:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzbWFsbHNvdXAiLCJpYXQiOjE1Mjg5MDIxOTUsImV4cCI6MTUyODk4ODYzOCwiYXVkIjoid3d3LnNtYWxsc291cC5jb20iLCJzdWIiOiJzbWFsbHNvdXBAcXEuY29tIiwidXNlcklkIjoiMDQxOCJ9.fjjbA93FTcE71hz_cyIzCUFYdTdyl9hA0w7Pa0ltduc
实际上https://jwt.io/这个网站提供了这个能力,以及各种语言的生成token和解密token的库。

go语言生成token和解析token:
下面是go语言版的生成token和解析token的案例:
package main
import (
"github.com/dgrijalva/jwt-go"
"fmt"
)
func main() {
hmacSampleSecret := []byte("mysecret")
// Create a new token object, specifying signing method and the claims
// you would like it to contain.
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"iss": "smallsoup",
"iat": 1528902195,
"exp": 1528988638,
"aud": "www.smallsoup.com",
"sub": "smallsoup@qq.com",
"userId": "0418",
})
// Sign and get the complete encoded token as a string using the secret
tokenString, err := token.SignedString(hmacSampleSecret)
fmt.Println(tokenString, err)
token, err = jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
return hmacSampleSecret, nil
})
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
fmt.Println(claims)
} else {
fmt.Println(err)
}
}
具体可以了解github上以下代码的实现。
go get github.com/dgrijalva/jwt-go
本公众号免费提供csdn下载服务,海量IT学习资源,如果你准备入IT坑,励志成为优秀的程序猿,那么这些资源很适合你,包括但不限于java、go、python、springcloud、elk、嵌入式 、大数据、面试资料、前端 等资源。同时我们组建了一个技术交流群,里面有很多大佬,会不定时分享技术文章,如果你想来一起学习提高,可以公众号后台回复【2】,免费邀请加技术交流群互相学习提高,会不定期分享编程IT相关资源。
扫码关注,精彩内容第一时间推给你

浅谈json web token及应用的更多相关文章
- 什么是JWT(JSON WEB TOKEN)
转自于:http://www.jianshu.com/p/576dbf44b2ae 什么是JWT Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准( ...
- JWT(Json web token)简介
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(S ...
- JWT(Json web token)认证详解
JWT(Json web token)认证详解 什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该to ...
- ( 转 ) 什么是 JWT -- JSON WEB TOKEN
什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...
- 使用Json Web Token设计Passport系统
>>Token Auth机制 基于Token的身份验证是无状态的,我们不将用户信息存在服务器或Session中. 相比原始的Cookie+Session方式,更适合分布式系统的用户认证,绕 ...
- 浅谈大型web系统架构
动态应用,是相对于网站静态内容而言,是指以c/c++.php.Java.perl..net等服务器端语言开发的网络应用软件,比如论坛.网络相册.交友.BLOG等常见应用.动态应用系统通常与数据库系统. ...
- JWT【JSON Web Token】 简述
draft: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html http://tools.ietf.org/html/ ...
- 八幅漫画理解使用JSON Web Token设计单点登录系统
用jwt这种token的验证方式,是不是必须用https协议保证token不被其他人拦截? 是的.因为其实只是Base64编码而已,所以很容易就被解码了.如果你的JWT被嗅探到,那么别人就可以相应地解 ...
- JSON Web Token - 在Web应用间安全地传递信息(zhuan)
来自 http://blog.leapoahead.com/2015/09/06/understanding-jwt/ JSON Web Token(JWT)是一个非常轻巧的规范.这个规范允许我们使用 ...
随机推荐
- 关于volatile关键字的最佳解释
直接放原博主链接,真的写得非常好,看懂这个面试官问再多也不怕了: https://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatil ...
- HashMap面试必问的数据结构相关知识
如果在看这篇文章时,对HashMap的结构还不是很了解,建议你参考前段时间写的<刨死你系列——HashMap剖析(基于jdk1.8)>,可能会对下面的提及到知识点有些帮助. 1:HashM ...
- HTTPS加密协议
使用JDK自带的keytool工具生成一个证书(keystore文件),其中包含了密钥. a.在命令行输入以下命令:keytool -genkey -alias tbb -keyalg RSA -ke ...
- Json的动态解析
最近在项目中需要动态解析json,但解析json的方式有很多,如何合理的解析就是我们需要考虑的问题?比如Newtonsoft.Json.Linq下提供的JToken.JObject等,Newtonso ...
- centos7下mysql 用户管理和权限设置
1.进入mysql命令行,输入root及密码[root@localhost ~]# mysql -u root -pEnter password: Welcome to the MySQL monit ...
- 36 (OC)* MVC和MVVM
1:MVC (Modal View Controller)(模型 视图 控制器) 一.MVC 从字面意思来理解,MVC 即 Modal View Controller(模型 视图 控制器),是 Xe ...
- Linux遇到的问题-记录
Linux遇到的问题 2019-04-09以前: Linux&Win双系统下时间显示不正常的问题 一般安装了双系统(Linux+Windows)就很容易出现问题,Windows是直接取硬件时间 ...
- web-文件上传漏洞总结
思维导图: 一,js验证绕过 1.我们直接删除代码中onsubmit事件中关于文件上传时验证上传文件的相关代码即可. 或者可以不加载所有js,还可以将html源码copy一份到本地,然后对相应代码进行 ...
- Mysql学习笔记整理之数据库优化
数据库性能瓶颈的原因 数据库连接数 数据量大 硬件资源限制 数据性能优化方案 sql优化 2.缓存 3.建好索引 4.读写分离 5. 分库分表 慢日志查 ...
- 素数路径Prime Path POJ-3126 素数,BFS
题目链接:Prime Path 题目大意 从一个四位素数m开始,每次只允许变动一位数字使其变成另一个四位素数.求最终把m变成n所需的最少次数. 思路 BFS.搜索的时候,最低位为0,2,4,6,8可以 ...