加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

golang的token方法

(2024-07-05 08:44:22)
分类: Go
go get -u github.com/gin-gonic/gin
go get -u github.com/dgrijalva/jwt-go

package main

import (
    "net/http"
    "time"

    "github.com/gin-gonic/gin"
    "github.com/dgrijalva/jwt-go"
)

var (
    jwtKey = []byte("your_secret_key")
)

// Claims 结构定义
type Claims struct {
    Username string `json:"username"`
    jwt.StandardClaims
}

func main() {
    router := gin.Default()

    // 登录端点,用于获取JWT Token
    router.POST("/login", loginHandler)

    // 使用JWT中间件保护需要验证的端点
    auth := router.Group("/auth")
    auth.Use(authMiddleware())
    {
        auth.GET("/data", dataHandler)
    }

    router.Run(":8080")
}

// 处理登录,生成JWT Token
func loginHandler(c *gin.Context) {
    var loginVals struct {
        Username string `json:"username"`
        Password string `json:"password"`
    }

    if err := c.ShouldBindJSON(&loginVals); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid login details"})
        return
    }

    // 实际情况下,这里应该验证用户名和密码

    // 生成JWT Token
    expirationTime := time.Now().Add(5 * time.Minute)
    claims := &Claims{
        Username: loginVals.Username,
        StandardClaims: jwt.StandardClaims{
            ExpiresAt: expirationTime.Unix(),
        },
    }

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    tokenString, err := token.SignedString(jwtKey)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
        return
    }

    c.JSON(http.StatusOK, gin.H{"token": tokenString})
}

// JWT 验证中间件
func authMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        tokenString := c.GetHeader("Authorization")
        if tokenString == "" {
            c.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization header required"})
            c.Abort()
            return
        }

        token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
            return jwtKey, nil
        })

        if err != nil {
            c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
            c.Abort()
            return
        }

        if !token.Valid {
            c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
            c.Abort()
            return
        }

        // 将claims信息存储在上下文中,供后续请求处理函数使用
        claims, ok := token.Claims.(*Claims)
        if !ok {
            c.JSON(http.StatusUnauthorized, gin.H{"error": "Failed to parse claims from token"})
            c.Abort()
            return
        }

        c.Set("username", claims.Username)
        c.Next()
    }
}

// 受保护的数据端点
func dataHandler(c *gin.Context) {
    username := c.GetString("username")
    c.JSON(http.StatusOK, gin.H{"data": "protected data for " + username})
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有