基于gin的JWT跨域认证
写了一个demo
package main
import (
"errors"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"log"
"net/http"
"strings"
"time"
)
type UserInfo struct {
Username string `json:"username" xml:"username" form:"username" binding:"required"`
Password string `json:"password" xml:"password" form:"password" binding:"required"`
}
type MyClaims struct {
Username string
jwt.StandardClaims
}
const TokenExpireDuration = time.Minute*10
var MySecret = []byte("mysecret")
func GenToken(username string) (string,error) {
c := MyClaims{
username,
jwt.StandardClaims{
ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(),
Issuer: "my-project",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256,c)
return token.SignedString(MySecret)
}
func ParseToken(tokenString string) (*MyClaims,error) {
token,err := jwt.ParseWithClaims(tokenString,MyClaims{}, func(token *jwt.Token) (interface{}, error) {
return MySecret,nil
})
if err !=nil{
return nil,err
}
if claims ,ok := token.Claims.(*MyClaims);ok && token.Valid{
return claims,nil
}
return nil,errors.New("invalid token")
}
func authHandler(c *gin.Context) {
var user UserInfo
if err := c.ShouldBind(&user);err !=nil{
c.JSON(http.StatusOK,gin.H{
"code":2001,
"msg":"无效的参数",
})
return
}
// 校验
if user.Username == "test" && user.Password == "test"{
tokenString,_ := GenToken(user.Username)
c.JSON(http.StatusOK,gin.H{
"cooe":2000,
"msg":"success",
"data":gin.H{"token":tokenString},
})
return
}
c.JSON(http.StatusOK,gin.H{
"code":2002,
"msg":"鉴权失败",
})
return
}
//定义一个中间件,进行token的校验
func JWTAuthMiddleware() gin.HandlerFunc{
return func(c *gin.Context) {
// 携带token的三种方式: 1,放在请求头,2,放在请求体,3,放在url中
authHeader := c.Request.Header.Get("Authorization")
if authHeader == ""{
c.JSON(http.StatusOK,gin.H{
"code":2003,
"msg":"请求体中auth为空",
})
c.Abort()
return
}
// 按照空格分隔
parts := strings.SplitN(authHeader," ",2)
if !(len(parts) ==2 && parts[0] == "Bearer"){
c.JSON(http.StatusOK,gin.H{
"code":2005,
"msg":"无效的token00",
})
c.Abort()
return
}
// parts[1]是获取到的tokenString,我们使用之前定义好的解析JWT的函数来解析它
mc,err := ParseToken(parts[1])
if err !=nil{
c.JSON(http.StatusOK,gin.H{
"code":2005,
"msg":"无效的token11",
})
c.Abort()
return
}
c.Set("username",mc.Username)
c.Next()
}
}
func main() {
r := gin.Default()
r.Static("/static","./static")
r.LoadHTMLGlob("templates/**/*")
r.GET("/login", func(c *gin.Context) {
c.HTML(http.StatusOK,"login/login.html",nil)
})
r.POST("/auth",authHandler)
r.GET("/home",JWTAuthMiddleware(), func(c *gin.Context) {
username := c.MustGet("username")
c.JSON(http.StatusOK,gin.H{
"code":2000,
"msg":"success",
"data":gin.H{"username":username},
})
})
if err := r.Run(":8081");err !=nil{
log.Println("start failed err :",err)
}
}

浙公网安备 33010602011771号