Go-jwt

简介: Go-jwt

Go-jwt

简介

jwt 和 token 类似,在服务端加入一个 secret 密钥,又用户发送用户名密码给服务端,服务端验证,验证成功后就生成三个部分 header,payload,signature 组成的 jwt token 给客户端,之后的请求都带上 jwt token,服务端通过 secret 密钥进行验证。

缺点:无法中途废弃

安装

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

使用步骤

1、生成解析token

import (
    "errors"
    "github.com/dgrijalva/jwt-go"
    "time"
)

// 自定义 secret
var jwtSecret = []byte("testtest")

//Claim是一些实体(通常指的用户)的状态和额外的元数据
type Claims struct {
   
    Username string `json:"username"`
    Password string `json:"password"`
    jwt.StandardClaims
}

// 根据用户的用户名和密码产生token
func GenerateToken(username, password string) (string, error) {
   
    //设置token有效时间
    nowTime := time.Now()
    expireTime := nowTime.Add(3 * time.Hour)

    claims := Claims{
   
        Username: username,
        Password: password,
        StandardClaims: jwt.StandardClaims{
   
            // 过期时间
            ExpiresAt: expireTime.Unix(),
            // 指定token发行人
            Issuer: "gin-blog",
        },
    }

    tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    //该方法内部生成签名字符串,再用于获取完整、已签名的token
    token, err := tokenClaims.SignedString(jwtSecret)
    return token, err
}

// 根据传入的token值获取到Claims对象信息,(进而获取其中的用户名和密码)
func ParseToken(token string) (*Claims, error) {
   

    //用于解析鉴权的声明,方法内部主要是具体的解码和校验的过程,最终返回*Token
    tokenClaims, err := jwt.ParseWithClaims(token, &Claims{
   }, func(token *jwt.Token) (interface{
   }, error) {
   
        return jwtSecret, nil
    })
    if err != nil {
   
        return nil, err
    }
    if tokenClaims != nil {
   
        // 从tokenClaims中获取到Claims对象,并使用断言,将该对象转换为我们自己定义的Claims
        // 要传入指针,项目中结构体都是用指针传递,节省空间。
        if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
   
            return claims, nil
        }
    }
    return nil, errors.New("invalid token")
}

2、jwt 中间件

import (
    "devops/pkg/jwtOperation"
    "github.com/gin-gonic/gin"
    "net/http"
    "strings"
)

// JWTAuthMiddleware 基于JWT的认证中间件--验证用户是否登录
func JWTAuthMiddleware() func(c *gin.Context) {
   
    return func(c *gin.Context) {
   
        authHeader := c.Request.Header.Get("authorization")
        if authHeader == "" {
   
            c.JSON(http.StatusUnauthorized, gin.H{
   
                "code": 2003,
                "msg":  "请求头中auth为空",
            })
            c.Abort()
            return
        }
        // 按空格分割
        parts := strings.Split(authHeader, ".")
        if len(parts) != 3 {
   
            c.JSON(http.StatusUnauthorized, gin.H{
   
                "code": 2004,
                "msg":  "请求头中auth格式有误",
            })
            c.Abort()
            return
        }
        mc, ok := jwtOperation.ParseToken(authHeader)
        if ok != nil {
   
            c.JSON(http.StatusUnauthorized, gin.H{
   
                "code": 2005,
                "msg":  "无效的Token",
            })
            c.Abort()
            return
        }
        //m := mc.Username
        // 将当前请求的username信息保存到请求的上下文c上
        c.Set("username", mc.Username)
        c.Next() // 后续的处理函数可以用过c.Get("username")来获取当前请求的用户信息
    }
}

3、测试登录

func AuthLoginHandler(c *gin.Context) {
   
    // 用户发送用户名和密码过来
    var user models.DevopsAuthModel
    err := c.ShouldBindJSON(&user)
    if err != nil {
   
        c.JSON(http.StatusBadRequest, gin.H{
   
            "code": 2001,
            "msg":  "无效的参数",
        })
        return
    }
    tokenString, _ := jwtOperation.GenerateToken(user.UserName, user.Password)
    c.JSON(http.StatusOK, gin.H{
   
        "code":     2000,
        "msg":      "success",
        "Token":    tokenString,
        "username": user.UserName,
    })
}

4、路由接入 jwt 中间件

func Routers(e *gin.Engine) {
   
  e.POST("/login", controllers.AuthLoginHandler)
  demo1 := e.Group("/demo1")
    demo1.Use(middleware.JWTAuthMiddleware())
    {
   
        demo1.GET("/get", controllers.GetHandler)
        demo1.POST("/post", controllers.GetHandler)
    }
}
相关文章
|
安全 Go
Go语言函数实现接口的N个实践技巧
Go语言函数实现接口的N个实践技巧
205 0
|
安全 架构师 应用服务中间件
Nginx极简入门(五)配置Nginx反向代理
反向代理(Reverse Proxy)则是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器
Nginx极简入门(五)配置Nginx反向代理
|
5月前
|
数据可视化 测试技术 Go
Go 语言测试与调试:`go test` 工具用法
`go test` 是 Go 语言内置的测试工具,支持单元测试、基准测试、示例测试等功能。本文详解其常用参数、调试技巧及性能测试命令,并提供实际项目中的应用示例与最佳实践。
|
安全 Go
用 Zap 轻松搞定 Go 语言中的结构化日志
在现代应用程序开发中,日志记录至关重要。Go 语言中有许多日志库,而 Zap 因其高性能和灵活性脱颖而出。本文详细介绍如何在 Go 项目中使用 Zap 进行结构化日志记录,并展示如何定制日志输出,满足生产环境需求。通过基础示例、SugaredLogger 的便捷使用以及自定义日志配置,帮助你在实际开发中高效管理日志。
391 1
|
传感器 网络协议 物联网
手把手教你在 Windows 环境中搭建 MQTT 服务器
手把手教你在 Windows 环境中搭建 MQTT 服务器
1782 0
|
存储 搜索推荐 Linux
2024年 15 个最佳免费开源 Linux 文件管理器
【4月更文挑战第25天】
11010 53
2024年 15 个最佳免费开源 Linux 文件管理器
|
存储 NoSQL 算法
深入理解Redis数据类型Zset原理
本文深入探讨了Redis中的Zset(有序集合)数据类型,它是一种可以存储排序功能的集合,其中每个元素都具有一个浮点型的score属性,用于根据score进行排序。
深入理解Redis数据类型Zset原理
|
XML 安全 API
AndroidManifest.xml文件综合详解
AndroidManifest.xml文件综合详解
873 2
|
存储 JSON Java
spring boot3登录开发-1(整合jwt)
spring boot3登录开发-1(整合jwt)
551 1
|
关系型数据库 API Go
[golang]在Gin框架中使用JWT鉴权
[golang]在Gin框架中使用JWT鉴权
312 0