首页 > 其他分享 >golang 中 Jwt 的验证及续期使用

golang 中 Jwt 的验证及续期使用

时间:2024-07-04 18:52:22浏览次数:16  
标签:secretKey err Jwt jwt Token golang token gin 续期

创建Utils的Jwt文件,用于创建Jwt Token  和    验证并继期

package utils

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

// 生成Jwt Token
// @Param  secretKey 表示jwt secretKey【*******注意:发布多台时secretKey 必须一样*********】
// @Result  string 创建的Token
// @Result  error 返回验证错误信息

func GenerateJWTToken() (string, error) {
    // secretKey 表示jwt 的secretKey【*******注意:发布多台时secretKey 必须一样,否则通不过验证*********】
    // 获取 ini 文件配置的 Jwt SecretKey
    var secretKey = GetIniVale("jwt", "SecretKey")
    claims := jwt.MapClaims{
        "sub":  "1234567890",
        "name": "John Doe",
        "iat":  time.Now().Unix(),
        "exp":  time.Now().Add(time.Minute * 3).Unix(),
    }
    // 使用指定的签名方法和密钥创建令牌
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    tokenString, err := token.SignedString([]byte(secretKey))
    if err != nil {
        return "", err
    }
    return tokenString, nil
}

// 验证Jwt token  并且如果Token快过期,就创建新的token
// @Param  tokenString 表示jwt token
// @Result  bool 验证是否通过
// @Result  string 快过期创建新的Token,没有则为空
// @Result  error 返回验证错误信息

func ValidateJWTToken(tokenString string) (bool, string, error) {
    // secretKey 表示jwt 的secretKey【*******注意:发布多台时secretKey 必须一样,否则通不过验证*********】
    // 获取 ini 文件配置的 Jwt SecretKey
    var secretKey = GetIniVale("jwt", "SecretKey")
    tokenString = strings.TrimPrefix(tokenString, "Bearer ")
    token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
        return []byte(secretKey), nil
    })
    if err != nil {
        return false, "", err
    }
    claims, ok := token.Claims.(jwt.MapClaims)
    // token 验证
    if ok && token.Valid {
        // Token是否过期
        if !claims.VerifyExpiresAt(time.Now().Unix(), false) {
            return false, "", errors.New("access token expired")
        }
        // 一分钟过期就重新添加一个Token 返回给前端
        if !claims.VerifyExpiresAt(time.Now().Add(time.Minute).Unix(), false) {
            newToken, _ := GenerateJWTToken()
            return true, newToken, nil
        }
        return true, "", nil
    } else {
        return false, "", fmt.Errorf("Invalid token")
    }
}

编写登录创建jwt token

package controller

import (
    "github.com/gin-gonic/gin"
    "jwt/utils"
)

type UserController struct{}

func (u UserController) Login(c *gin.Context) {
    userName := c.Query("userName")
    pwd := c.Query("password")
    if userName == "zs" && pwd == "123" {
        // 登录成功  生成Jwt Token
        token, err := utils.GenerateJWTToken()
        if err != nil {
            c.JSON(500, gin.H{"Msg": "生成Token失败:" + err.Error()})
        } else {
            c.JSON(200, gin.H{"Token": token})
        }
    } else {
        c.JSON(500, gin.H{"Msg": "用户中或密码错误!"})
    }
}

在gin 中 添加中间件,用于验证 token

package middleware

import (
    "github.com/gin-gonic/gin"
    "jwt/utils"
    "strings"
)

func ValidataToken() gin.HandlerFunc {
    return func(c *gin.Context) {    // 判断 是不是登录链接,如果是直接往下走
        if strings.Contains(strings.ToLower(c.Request.RequestURI), "/user/login") {
            c.Next()
        } else {
            token := c.GetHeader("Authorization")
            // 验证token  并且如果 Token快过期 就创建新的token
            bls, newToken, err := utils.ValidateJWTToken(token)
            if err != nil {
                c.JSON(500, gin.H{
                    "msg": err.Error(),
                })
                c.Abort()
                return
            } else {
                if bls {
                    // 是否有快过期创建新的Token
                    if len(newToken) > 0 {
                        c.Header("newToken", newToken) // 将新Token添加到返回的Header里,方便前端使用
                    }
                    c.Next()
                } else {
                    c.JSON(401, gin.H{"msg": "token not validated"})
                    c.Abort()
                    return
                }
            }
        }

    }
}

gin 中use中间件

package main

import (
    "github.com/gin-gonic/gin"
    "jwt/middleware"
    "jwt/route"
)

func main() {
    r := gin.Default()
    r.Use(middleware.ValidataToken())
    route.AddUserInfoRoute(r)
    r.Run(":8080")
}

 

标签:secretKey,err,Jwt,jwt,Token,golang,token,gin,续期
From: https://www.cnblogs.com/yingger/p/18284466

相关文章

  • golang 内存逃逸 你应该知道的知识
    逃逸分析目录1.为什么要了解内存逃逸2.什么是逃逸分析3.内存逃逸的影响-性能和稳定性4.内存逃逸的原因5.内存逃逸的检测6.如何避免内存逃逸7.内存逃逸代码示例原文链接:一文弄懂Golang中的内存逃逸1.为什么要了解内存逃逸-内存逃逸是Go语言编程中一个特别需要注意的问......
  • golang 打印类型和switch case选择
    因为需要打印传输信息,要用到pion的stats,而stats返回报告的又包含多个type,对于不同type有不同的数据统计,所以需要打印类型和switchcase针对于不同的type执行不同的命令。针对于返回变量类型,golang采用reflect包,对于变量valua,可以利用reflect.TypeOf(valua)返回变量类型,而这只能做......
  • 揭秘JWT:从CTF实战到Web开发,使用JWT令牌验证
    揭秘JWT:从CTF实战到Web开发,使用JWT令牌验证介绍JWT(JSONWebTokens)是一种开放标准(RFC7519),它定义了一种紧凑且自包含的方式,用于在网络上安全地传输信息。这种信息可以验证和信任,因为它是数字签名的。JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。「优点」:「无状态」:服......
  • Golang面试:泛型
    Go语言在1.18版本中引入了泛型(Generics),这是Go语言发展中的一个重要里程碑。泛型允许你编写更通用和可复用的代码,而无需牺牲类型安全性。以下是对Go中泛型的详细介绍,包括其语法、使用场景和示例代码。1.泛型的基本概念泛型允许你定义可以处理多种数据类型的函数和数据结构,而无需......
  • Golang开发:构建支持并发的网络爬虫
    Golang开发:构建支持并发的网络爬虫随着互联网的快速发展,获取网络数据成为了许多应用场景中的关键需求。网络爬虫作为一种自动化获取网络数据的工具,也因此迅速崛起。而为了应对日益庞大的网络数据,开发支持并发的爬虫成为了必要的选择。本文将介绍如何使用Golang编写一个支持......
  • 手把手带你使用JWT实现单点登录
    JWT(英文全名:JSONWebToken)是目前最流行的跨域身份验证解决方案之一,今天我们一起来揭开它神秘的面纱!一、故事起源说起JWT,我们先来谈一谈基于传统session认证的方案以及瓶颈。传统session交互流程,如下图:当浏览器向服务器发送登录请求时,验证通过之后,会将用户信息存入seesion中......
  • Golang 依赖注入设计哲学|12.6K 的依赖注入库 wire
    一、前言线上项目往往依赖非常多的具备特定能力的资源,如:DB、MQ、各种中间件,以及随着项目业务的复杂化,单一项目内,业务模块也逐渐增多,如何高效、整洁管理各种资源十分重要。本文从“术”层面,讲述“依赖注入”的实现,带你体会其对于整洁架构&DDD等设计思想的落地,起到的支撑作用。......
  • 【力扣 - 每日一题】3115. 质数的最大距离(一次遍历、头尾遍历、空间换时间、埃式筛、
    原题链接题目描述给你一个整数数组nums。返回两个(不一定不同的)质数在nums中下标的最大距离。示例1:输入:nums=[4,2,9,5,3]输出:3解释:nums[1]、nums[3]和nums[4]是质数。因此答案是|4-1|=3。示例2:输入:nums=[4,8,2,8]输出:0解释:nums[2]是质......
  • golang 构建标签(go:build)条件编译
     //go:build是Go语言(golang)中的一种构建标签(buildtag),用于控制源代码文件在特定条件下是否被编译。这个注释标记允许你在同一个包内编写针对不同平台、操作系统或编译条件的代码。当gobuild或gotest等命令执行时,它们会检查这些标签来决定哪些文件应该包含在构建过程中......
  • 区分公有地址和私有地址, golang实现
     区分公有地址(PublicIPAddresses)和私有地址(PrivateIPAddresses)主要依据它们的分配、使用范围以及是否能在全球互联网上直接路由。 以下是一些关键区别:  分配和管理: 公有地址:由互联网地址分配机构(InternetAssignedNumbersAuthority,IANA)管理......