首页 » PHP教程 » phpjwt示例技巧_golang之JWT实现的示例代码

phpjwt示例技巧_golang之JWT实现的示例代码

访客 2024-12-09 0

扫一扫用手机浏览

文章目录 [+]

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

直白的讲jwt便是一种用户认证(差异于session、cookie)的办理方案。

phpjwt示例技巧_golang之JWT实现的示例代码

涌现的背景

phpjwt示例技巧_golang之JWT实现的示例代码
(图片来自网络侵删)

众所周知,在jwt涌现之前,我们已经有session、cookie来办理用户登录等认证问题,为什么还要jwt呢?

这里我们先理解一下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通过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、HS384Payload:载荷又称为Claim,携带的信息,比如用户名、过期韶光等,一样平常叫做 ClaimSignature:署名,是由header、payload 和你自己掩护的一个 secret 经由加密得来的

jwt利用

这里推举个利用比较多的开源项目[github.com/dgrijalva/jwt-go](),更多文档。

示例:

package mainimport ( "fmt" "github.com/dgrijalva/jwt-go" "time")const ( SECRETKEY = "243223ffslsfsldfl412fdsfsdf"//私钥)//自定义Claimstype CustomClaims struct { UserId int64 jwt.StandardClaims}func main() { //天生token maxAge:=606024 customClaims :=&CustomClaims{ UserId: 11,//用户id StandardClaims: jwt.StandardClaims{ ExpiresAt: time.Now().Add(time.Duration(maxAge)time.Second).Unix(), // 过期韶光,必须设置 Issuer:"jerry", // 非必须,也可以添补用户名, }, } //采取HMAC SHA256加密算法 token:=jwt.NewWithClaims(jwt.SigningMethodHS256, customClaims) tokenString,err:= token.SignedString([]byte(SECRETKEY)) if err!=nil { fmt.Println(err) } fmt.Printf("token: %v\n", tokenString) //解析token ret,err :=ParseToken(tokenString) if err!=nil { fmt.Println(err) } fmt.Printf("userinfo: %v\n", ret)}//解析tokenfunc ParseToken(tokenString string)(CustomClaims,error) { token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token jwt.Token) (interface{}, error) { if _, ok := token.Method.(jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) } return []byte(SECRETKEY), nil }) if claims, ok := token.Claims.(CustomClaims); ok && token.Valid { return claims,nil } else { return nil,err }}

运行结果:

token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjExLCJleHAiOjE1OTA5MTk1NDAsImlzcyI6ImplcnJ5In0.FppmbbHRrS4wd5wen73vYPOvtzycOrn2JZlK6JRjEGk userinfo: &{11 { 1590919540 0 jerry 0 }}

以上用到了CustomClaims,也可以用大略的方法

示例

package mainimport ( "fmt" "github.com/dgrijalva/jwt-go" "time")const ( SECRETKEY = "243223ffslsfsldfl412fdsfsdf"//私钥)//自定义Claimstype CustomClaims struct { UserId int64 jwt.StandardClaims}func main() { //天生token maxAge:=606024 // Create the Claims //claims := &jwt.StandardClaims{ // // ExpiresAt: time.Now().Add(time.Duration(maxAge)time.Second).Unix(), // 过期韶光,必须设置, // // Issuer: "jerry",// 非必须,也可以添补用户名, // //} //或者用下面自定义claim claims := jwt.MapClaims{ "id": 11, "name": "jerry", "exp": time.Now().Add(time.Duration(maxAge)time.Second).Unix(), // 过期韶光,必须设置, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenString, err := token.SignedString([]byte(SECRETKEY)) if err!=nil { fmt.Println(err) } fmt.Printf("token: %v\n", tokenString) //解析token ret,err :=ParseToken(tokenString) if err!=nil { fmt.Println(err) } fmt.Printf("userinfo: %v\n", ret)}//解析tokenfunc ParseToken(tokenString string)(jwt.MapClaims,error) { 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 []byte(SECRETKEY), nil }) if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { return claims,nil } else { return nil,err }}

运行结果类似

token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1OTA5MzUzMDUsImlkIjoxMSwibmFtZSI6ImplcnJ5In0.fapE0IiOEe_TqoMCThbNTHUvgWiHPEk0rm-9uPIcvPU userinfo: map[exp:1.590935305e+09 id:11 name:jerry]

小结:

做事端天生的jwt返回客户端可以存到cookie也可以存到localStorage中(比较cookie容量大),存在cookie中需加上 HttpOnly 的标记,可以防止 XSS) 攻击。
只管即便用https带证书网址访问。
session和jwt没有绝对好与不好,各有其善于的运用环境,请根据实际情形选择。

标签:

相关文章

phpcsv星号技巧_Joom平台CSV文件介绍产品篇

文本内部链接——基本属性——变型属性——图片链接——补充属性卖家可以利用CSV文件来批量上传产品、编辑产品、删除产品属性、禁用和启...

PHP教程 2024-12-11 阅读0 评论0