golang的token方法
2024-07-05 08:44阅读:
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})
}