轨道 · 写下来的字

go-jwt

2020.01.07

jwt 生成

// GenerateJWT  jwt generate
func (service UserLoginService) GenerateJWT(user model.User) (string, error) {
	expiresTime := time.Now().Unix() + int64(config.OneDayOfHours)
	ID := fmt.Sprint(user.ID)
	claims := CustomClaims{
		user.Username,
		jwt.StandardClaims{
			Audience:  "Audience",        // 受众
			ExpiresAt: expiresTime,       // 失效时间
			Id:        ID,                // 编号
			IssuedAt:  time.Now().Unix(), // 签发时间
			Issuer:    "gin project",     // 签发人
			NotBefore: time.Now().Unix(), // 生效时间
			Subject:   "login",           // 主题
		},
	}

	tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// 通过密码和保留字段加密
	var jwtSecret = []byte(config.Secret + user.PasswordDigest)
	token, err := tokenClaims.SignedString(jwtSecret)

	return token, err
}

中间件验证代码

package middleware

import (
	"encoding/json"
	"gin_project/config"
	"gin_project/model"
	"log"
	"net/http"
	"strconv"
	"strings"

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

// CustomClaims 自定义jwt
type CustomClaims struct {
	User string `json:"user"`
	jwt.StandardClaims
}

// Auth 权限认证
func Auth() gin.HandlerFunc {
	return func(context *gin.Context) {

		result := model.Result{
			Code:    http.StatusUnauthorized,
			Message: "无法认证,重新登录",
			Data:    nil,
		}
		auth := context.Request.Header.Get("Authorization")

		if len(auth) == 0 {
			context.Abort()
			context.JSON(http.StatusUnauthorized, result)
			return
		}

		fields := strings.Fields(auth)
		if len(fields) < 2 || fields[0] != "Bearer" {
			context.AbortWithStatusJSON(http.StatusUnauthorized, result)
			return
		}
		auth = fields[1]
		// 校验token
		claims, err := parseToken(auth)
		if err != nil {
			result.Message = "token error " + err.Error()
			context.AbortWithStatusJSON(http.StatusUnauthorized, result)
		} else {
			println("token 正确")
		}
		context.Set("claims", claims)

		context.Next()
	}
}

func parseToken(token string) (*CustomClaims, error) {
	// 分割出来载体
	payload := strings.Split(token, ".")
	bytes, e := jwt.DecodeSegment(payload[1])

	if e != nil {
		println(e.Error())
	}
	var cm CustomClaims
	//使用 json.Unmarshal(data []byte, v interface{})进行转换,返回 error 信息
	if err := json.Unmarshal(bytes, &cm); err != nil {
		log.Println(err)
	}
	i := cm.Id
	ID, err := strconv.Atoi(i)
	if err != nil {
		println(err.Error())
	}
	user := model.User{}
	user.ID = uint(ID)
	u := model.User.QueryByID(user)
	jwtToken, err := jwt.ParseWithClaims(token, &CustomClaims{},
		func(token *jwt.Token) (i interface{}, e error) {
			return []byte(config.Secret + u.PasswordDigest), nil
		})
	if err == nil && jwtToken != nil {
		if claim, ok := jwtToken.Claims.(*CustomClaims); ok && jwtToken.Valid {
			return claim, nil
		}
	}
	return nil, err
}
← 回到文章