[每周一更]-(第113期):JWT说明以及与Session,Cookie区别

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

直白的讲jwt就是一种用户认证(区别于session、cookie)的解决方案。

先了解一下session,cookie。

session

熟悉session运行机制的同学都知道,用户的session数据以file或缓存(redis、memcached)等方式存储在服务器端,客户端浏览器cookie中只保存sessionid。服务器端session属于集中存储,数量不大的情况下,没什么问题,当用户数据逐渐增多到一程度,就会给服务端管理和维护带来大的负担。

session有两个弊端:

1、无法实现跨域。

2、由于session数据属于集中管理里,量大的时候服务器性能是个问题。

优点:

1、session存在服务端,数据相对比较安全。

2、session集中管理也有好处,就是用户登录、注销服务端可控。

cookie

cookie也是一种解决网站用户认证的实现方式,用户登录时,服务器会发送包含登录凭据的Cookie到用户浏览器客户端,浏览器会将Cookie的key/value保存用户本地(内存或硬盘),用户再访问网站,浏览器会发送cookie信息到服务器端,服务器端接收cookie并解析来维护用户的登录状态。

cookie避免session集中管理的问题,但也存在弊端:

1、跨域问题。

2、数据存储在浏览器端,数据容易被窃取及被csrf攻击,安全性差。

优点:

1、相对于session简单,不用服务端维护用户认证信息。

2、数据持久性。

再谈JWT

jwt

jwt通过json传输,php、java、golang等很多语言支持,通用性比较好,不存在跨域问题。传输数据通过数据签名相对比较安全。客户端与服务端通过jwt交互,服务端通过解密token信息,来实现用户认证。不需要服务端集中维护token信息,便于扩展。当然jwt也有其缺点。

缺点:

1、用户无法主动登出,只要token在有效期内就有效。这里可以考虑redis设置同token有效期一直的黑名单解决此问题。

2、token过了有效期,无法续签问题。可以考虑通过判断旧的token什么时候到期,过期的时候刷新token续签接口产生新token代替旧token。

jwt设置有效期

可以设置有效期,加入有效期是为了增加安全性,即token被黑客截获,也只能攻击较短时间。设置有效期就会面临token续签问题,解决方案如下

通常服务端设置两个token

  • Access Token:添加到 HTTP 请求的 header 中,进行用户认证,请求接口资源。
  • refresh token:用于当 Access Token过期后,客户端传递refresh token刷新 Access Token续期接口,获取新的Access Token和refresh token。其有效期比 Access Token有效期长。

jwt构成:

  • Header:TOKEN 的类型,就是JWT,签名的算法,如 HMAC SHA256、HS384
  • Payload:载荷又称为Claim,携带的信息,比如用户名、过期时间等,一般叫做 Claim,前端直接拆分出这里,直接base64解密即可。
  • Signature:签名,是由header、payload 和你自己维护的一个 secret 经过加密得来的

Base64URL

前面提到,Header 和 Payload 串型化的算法是 Base64URL。这个算法跟 Base64 算法基本类似,但有一些小的不同。

JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。

Base64 有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。这就是 Base64URL 算法。

Claims

  • Audience string json:"aud,omitempty"

  • ExpiresAt int64 json:"exp,omitempty"

  • Id string json:"jti,omitempty"

  • IssuedAt int64 json:"iat,omitempty"

  • Issuer string json:"iss,omitempty"

  • NotBefore int64 json:"nbf,omitempty"

  • Subject string json:"sub,omitempty"

  • aud: 接收jwt的一方

  • exp: jwt的过期时间,这个过期时间必须要大于签发时间

  • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

  • iat: jwt的签发时间

  • iss: jwt签发者

  • nbf: 定义在什么时间之前,该jwt都是不可用的.就是这条token信息生效时间.这个值可以不设置,但是设定后,一定要大于当前Unix UTC,否则token将会延迟生效.

  • sub: jwt所面向的用户

服务端生成的jwt返回客户端可以存到cookie也可以存到localStorage中(相比cookie容量大),存在cookie中需加上 HttpOnly 的标记,可以防止 XSS) 攻击。

尽量用https带证书网址访问。

session和jwt没有绝对好与不好,各有其擅长的应用环境,请根据实际情况选择。

参考:

相关推荐
qq_1728055912 小时前
GO Govaluate
开发语言·后端·golang·go
littleschemer1 天前
Go缓存系统
缓存·go·cache·bigcache
程序者王大川2 天前
【GO开发】MacOS上搭建GO的基础环境-Hello World
开发语言·后端·macos·golang·go
Grassto2 天前
Gitlab 中几种不同的认证机制(Access Tokens,SSH Keys,Deploy Tokens,Deploy Keys)
go·ssh·gitlab·ci
高兴的才哥3 天前
kubevpn 教程
kubernetes·go·开发工具·telepresence·bridge to k8s
少林码僧3 天前
sqlx1.3.4版本的问题
go
蒙娜丽宁4 天前
Go语言结构体和元组全面解析
开发语言·后端·golang·go
蒙娜丽宁4 天前
深入解析Go语言的类型方法、接口与反射
java·开发语言·golang·go
三里清风_4 天前
Docker概述
运维·docker·容器·go
蒙娜丽宁4 天前
深入探讨Go语言中的切片与数组操作
开发语言·后端·golang·go