gin框架教程代码地址:

https://github.com/jiujuan/gin-tutorial

JWT介绍

JWT (JSON Web Token) 是一种规范。这个规范允许我们使用JWT在用户和服务器之间安全传递信息.

JWT的组成:

jwt分3个部分,Header 头部、Payload 载荷、Signature 签名, 用 dot(.) 点分开
一般像下面这个样子:
xxxx.yyyy.zzzz

Header:

一般表示算法和类型

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

JSON一般都会经过Base64Url编码

Payload:

payload包含claims, claims一般包含实体信息(user信息等)和额外的信息。其中claims又分3种类型:
Registered claims: 这个推荐设置的选项,但不是强制的。 它提供了一些有用的信息,iss (issuer), exp (expiration time), sub (subject), aud(audience), and others
Public claims:在使用JWTs时可以被定义。
Private claims:用户自定义的一些信息

example playload:

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

也会经过base64编码

Signature:

创建一个签名,我们要使用到header,payload 和 secret,在用算法计算他们
比如用 hmac sha256 算法:

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

计算出来长这个样子:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NjY1OTI3MjYsImlhdCI6MTU2NjU1NjcyNiwidXNlcl9pZCI6MSwicGFzc3dvcmQiOiIxMTEiLCJ1c2VybmFtZSI6InRvbSIsImZ1bGxfbmFtZSI6InRvbSIsInBlcm1pc3Npb25zIjpbXX0.HpkWP4CqlZBt-Ys_QYNs4yPd1GaR4oGxOeJU4In9co8

更多更详细介绍请参阅:https://jwt.io/introduction/

Go example

使用的go jwt库: https://github.com/dgrijalva/jwt-go,这个库有6k多的start,确实是很受欢迎,所以用这个库来写demo

demo例子:

package main

import (
"errors"
"fmt"
jwt "github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"net/http"
"time"
) const (
ErrorServerBusy = "server is busy"
ErrorReLogin = "relogin"
) type JWTClaims struct {
jwt.StandardClaims
UserID int `json:"user_id"`
Password string `json:"password"`
Username string `json:"username"`
} var (
Secret = "123#111" //salt
ExpireTime = 3600 //token expire time
) func main() {
r := gin.Default()
r.GET("/login/:username/:password", login)
r.GET("/verify/:token", verify)
r.GET("/refresh/:token", refresh)
r.GET("/sayHello/:token", sayHello)
_ = r.Run(":8000")
} //generate jwt token
func genToken(claims *JWTClaims) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
signedToken, err := token.SignedString([]byte(Secret))
if err != nil {
return "", errors.New(ErrorServerBusy)
}
return signedToken, nil
} //登录,获取jwt token
func login(c *gin.Context) {
username := c.Param("username")
password := c.Param("password")
claims := &JWTClaims{
UserID: 1,
Username: username,
Password: password,
}
claims.IssuedAt = time.Now().Unix()
claims.ExpiresAt = time.Now().Add(time.Second * time.Duration(ExpireTime)).Unix()
singedToken, err := genToken(claims)
if err != nil {
c.String(http.StatusNotFound, err.Error())
return
}
c.String(http.StatusOK, singedToken)
} //验证jwt token
func verifyAction(strToken string) (*JWTClaims, error) {
token, err := jwt.ParseWithClaims(strToken, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(Secret), nil
})
if err != nil {
return nil, errors.New(ErrorServerBusy)
} claims, ok := token.Claims.(*JWTClaims)
if !ok {
return nil, errors.New(ErrorReLogin)
}
if err := token.Claims.Valid(); err != nil {
return nil, errors.New(ErrorReLogin)
} fmt.Println("verify")
return claims, nil
} func sayHello(c *gin.Context) {
strToken := c.Param("token")
claim, err := verifyAction(strToken)
if err != nil {
c.String(http.StatusNotFound, err.Error())
}
c.String(http.StatusOK, "hello, ", claim.Username)
} func verify(c *gin.Context) {
strToken := c.Param("token")
claim, err := verifyAction(strToken)
if err != nil {
c.String(http.StatusNotFound, err.Error())
return
}
c.String(http.StatusOK, "verify: ", claim.Username)
} func refresh(c *gin.Context) {
strToken := c.Param("token")
claims, err := verifyAction(strToken)
if err != nil {
c.String(http.StatusNotFound, err.Error())
return
}
claims.ExpiresAt = time.Now().Unix() + (claims.ExpiresAt - claims.IssuedAt)
signedToken, err := genToken(claims)
if err != nil {
c.String(http.StatusNotFound, err.Error())
return
}
c.String(http.StatusOK, signedToken, ", ", claims.ExpiresAt)
}

JWT资源

对于jwt的了解: https://jwt.io
jwt介绍:https://jwt.io/introduction/
rfc: https://tools.ietf.org/html/rfc7519
jwt方法参数定义的介绍:https://www.iana.org/assignments/jwt/jwt.xhtml
jwt handbook: https://auth0.com/resources/ebooks/jwt-handbook

JWT各种库:https://jwt.io/#libraries

最新文章

  1. .Net中的AOP系列之构建一个汽车租赁应用
  2. WPF - 属性系统 (2 of 4)
  3. 【.NET深呼吸】(WPF)跨窗口完成绑定
  4. Daily Scrum02 12.16
  5. CRM客户关系管理系统 ——客户联系人添加(十五)
  6. 获取验证码,60秒倒计时js
  7. [MySQL] 字符集的选择
  8. 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10(转载)
  9. 利用Arcgis for javascript API绘制GeoJSON并同时弹出多个Popup
  10. python与C,在写程序时踩过的坑!
  11. Spring Security(15)——权限鉴定结构 RoleVoter
  12. swift - 3D 视图,截图,关键字搜索
  13. Nginx做转发
  14. 自然语言交流系统 phxnet团队 创新实训 个人博客 (十二)
  15. Dubbo学习笔记0:RPC框架Dubbo介绍
  16. 题解 P1420 【最长连号】
  17. 【翻译自mos文章】在一次失败的 'Shutdown Immediate'之后,数据库job 不能执行。
  18. RabbitMQ入门(4)——路由(Routing)
  19. [Python爬虫] 之十六:Selenium +phantomjs 利用 pyquery抓取一点咨询数据
  20. Spring配置dataSource的三种方式 数据库连接池

热门文章

  1. NoSQL数据库技术实战-第1章 NoSQL与大数据简介 NoSQL数据库的类型
  2. 【树形dp 思维题】HHHOJ#483. NOIP司马懿
  3. 运行别人的Vue项目
  4. Python3之Django框架搭建详细步骤
  5. WPF之Treeview实现MVVM双向绑定
  6. Codeforces 981 D.Bookshelves(数位DP)
  7. node链接mongoDB及封装
  8. JavaWeb_(SSH论坛)_一、项目入门
  9. 黑马lavarel教程---10、lavarel模型关联
  10. Redis内存碎片率