go: jwt配合中间件实现用户认证

实现的效果如下:通过后台下发token实现用户认证:


AuthMiddleware.go: 

package middleware

import (
	"ginEssential/common"
	"ginEssential/model"
	"github.com/gin-gonic/gin"
	"net/http"
	"strings"
)

/**
gin的中间件就是一个函数返回一个gin.HandlerFunc
 */
func AuthMiddleware() gin.HandlerFunc  {
	return func(ctx *gin.Context) {
		//获取authorization header
		tokenString := ctx.GetHeader("Authorization")

		// validate token formate
		if tokenString == "" || !strings.HasPrefix(tokenString,"Bearer ") {
			ctx.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg": "权限不足",
			})
			ctx.Abort()
			return
		}

		tokenString = tokenString[7:]

		//解析token
		token, claims, err := common.ParseToken(tokenString)
		if err != nil  || !token.Valid{
			ctx.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg": "权限不足",
			})
			ctx.Abort()
			return
		}

		//token通过了验证,获取token中userid
		userId := claims.UserId
		DB := common.GetDB()
		var user model.User
		DB.First(&user,userId)

		//用户
		if user.ID == 0  {//用户不存在
			ctx.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg": "权限不足",
			})
			ctx.Abort()
			return
		}

		//用户存在,将user信息写入上下文
		ctx.Set("user", user)

		ctx.Next()
	}
}

jwt.go:

package common

import (
	"ginEssential/model"
	"github.com/dgrijalva/jwt-go"
	"time"
)

/**
jwt : 实现用户认证和用户未知登录状态
 */
var jwtKey = []byte("a_secret_crect")

type Claims struct {
	UserId uint
	jwt.StandardClaims
}

/**
下发token
 */
func ReleaseToken(user model.User) (string, error) {
	//token的过期时间
	expireationTime := time.Now().Add(7*24*time.Hour)

	claims := &Claims{
		UserId:         user.ID,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expireationTime.Unix(),
			IssuedAt:time.Now().Unix(),
			Issuer: "yinlei",
			Subject: "用户主题",
		},
	}

	/**
	token的组成部分:
		//示例token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjUsImV4cCI6MTU4MzkzMTcwMSwiaWF0IjoxNTgzMzI2OTAxLCJpc3MiOiJ5aW5sZWkiLCJzdWIiOiLnlKjmiLfkuLvpopgifQ.BnO2oVHPshBMmqE7tlSac2VLjpk0Pb21e0zWX7Cym40

	1.token使用的加密协议
	2.playload:存储的是上面的具体信息
	3.hash(加密协议+playload+key)的值  【可使用base64解密】
	 */
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString(jwtKey)
	if err != nil {
		return "", err
	}

	return tokenString, nil
}

/**
解析token
 */
func ParseToken(tokenString string) (*jwt.Token, *Claims, error){
	claims := &Claims{}
	token, err := jwt.ParseWithClaims(tokenString,claims, func(token *jwt.Token) (i interface{}, e error) {
		return jwtKey, nil
	})
	return token, claims, err
}




这样就可以通过下发token并通过token配合jwt实现用户认证. 

token的下发应该在登录里:

发布了356 篇原创文章 · 获赞 67 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/qq_39969226/article/details/104663562