什么是JWT?

JWT全称JSON Web Token是一种跨域认证解决方案,属于一个开放的标准,它规定了一种Token实现方式,目前多用于前后端分离项目和OAuth2.0业务场景下。

JWT作用?

JWT就是一种基于Token的轻量级认证模式,服务端认证通过后,会生成一个JSON对象,经过签名后得到一个Token(令牌)再发回给用户,用户后续请求只需要带上这个Token,服务端解密之后就能获取该用户的相关信息了。

下载jwt

go get -u github.com/golang-jwt/jwt

生成JWT和解析JWT

我们在这里直接使用jwt-go这个库来实现我们生成JWT和解析JWT的功能。

定义需求

我们需要定制自己的需求来决定JWT中保存哪些数据

type MyClaims struct {
UserID uint64 `json:"user_id"`
Username string `json:"username"`
jwt.StandardClaims
}

定义JWT的过期时间和Secret(盐):

const TokenExpireDuration = time.Hour * 24 * 2 // 过期时间 -2天
var Secret = []byte("i am zhaohaiyu") // Secret(盐) 用来加密解密

生成JWT

//生成 jwt token
func genToken(userID uint64, username string) (string, error) {
var claims = MyClaims{
userID,
username,
jwt.StandardClaims{
ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
Issuer: "zhaohaiyu", // 签发人
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
signedToken, err := token.SignedString([]byte(Secret))
if err != nil {
return "", fmt.Errorf("生成token失败:%v", err)
}
return signedToken, nil
}

解析JWT

//验证jwt token
func ParseToken(tokenStr string) (*MyClaims, error) {
token, err := jwt.ParseWithClaims(tokenStr, &MyClaims{}, func(token *jwt.Token) (i interface{}, err error) { // 解析token
return Secret, nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*MyClaims); ok && token.Valid { // 校验token
return claims, nil
}
return nil, errors.New("invalid token")
}

在gin框架中使用JWT

r.POST("/auth/token", GetTokenHandler)

登录生成token

func GetTokenHandler(c *gin.Context) {
// 接收参数
var user UserInfo
err := c.ShouldBind(&user)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": 1001,
"err_info": "参数错误",
})
return
}
// 验证密码
if user.Username == "root" && user.Password == "123" {
// 生成Token
tokenString, err := GenToken(user.Username)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": 1001,
"err_info": "生成token错误",
})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 2000,
"msg": "success",
"data": gin.H{"token": tokenString},
})
return
} else {
c.JSON(http.StatusOK, gin.H{
"code": 2002,
"msg": "用户名或密码错误",
})
return
}
return
}

jwt中间件验证

// JWThMiddleware 中间件
func JWThMiddleware() func(c *gin.Context) {
return func(c *gin.Context) {
// 客户端携带Token有三种方式 1.放在请求头 2.放在请求体 3.放在URI
// 这里假设Token放在Header的token中
token := c.Request.Header.Get("token")
if token == "" {
// 处理 没有token的时候
c.Abort() // 不会继续停止
return
}
// 解析
mc, err := ParseToken(token)
if err != nil {
// 处理 解析失败
c.Abort()
return
}
// 将当前请求的userID信息保存到请求的上下文c上
c.Set("userID", mc.UserID)
c.Next()
}
}

最新文章

  1. 缺少.lib文件导致的Link2019 解决方案汇总
  2. springMVC-数据绑定流程
  3. js中Dom对象的position属性
  4. css基本样式总结
  5. java读取目录下所有csv文件数据,存入三维数组并返回
  6. 你真的了解try{ return }finally{}中的return?
  7. jsp的静态包含与动态包含:<%@ include file="" %>和<jsp:include page=""></jsp:include>区别与分析
  8. 【转】placement new
  9. 矩阵乘法 and BIOS loads MBR into 0x7C00?
  10. zoj 3714 Java Beans
  11. Mac Yosemite下Android Studio环境问题集合
  12. 恢复js文件在windows默认打开方式
  13. C#开发 “因为某项目未能生成,所以无法发布”
  14. 第九十节,html5+css3pc端固定布局,底部区域,说明区域,版权区域
  15. mysql安装教程以及配置快捷方式
  16. ElasticSearch 5.0.0 集群安装部署文档
  17. 解决WordPress无法上传媒体文件以及无法下载和安装主题与插件的问题
  18. 如果报错,使用 journalctl -f -t etcd 和 journalctl -u etcd 来定位问题。
  19. spring boot多模块项目找不到类
  20. PHP中你应该知道的require()文件包含的正确用法

热门文章

  1. sqldbx配置连接Oracle 12C数据库
  2. 虚拟机安装的kali操作系统实现共享文件夹
  3. python3中的缺省参数和global
  4. SQL Server 判断表名称、索引、表字段是否存在
  5. 来看看是什么原因导致生产服上的系统CPU高的?
  6. TCP实现聊天
  7. 1051 Pop Sequence (25分)栈
  8. 剖析虚幻渲染体系(10)- RHI
  9. Golang语言系列-07-函数
  10. ELK太重?试试KFC日志采集