go使用JWT进行身份验证

先编写生成token和解析token两个函数

package util

import (
    jwt "github.com/dgrijalva/jwt-go"

    "go-gin-example2/conf"
    "time"
)

var jwtSecret=[]byte(conf.AppSetting.JwtSecret)

type  Claims struct {
    Username string `json:"username"`
    Password string `json:"password"`
    jwt.StandardClaims
}

// 产生token的函数
func GenerateToken(username,password string)(string,error){
    nowTime :=time.Now()
    expireTime:=nowTime.Add(3*time.Hour)

    claims:=Claims{
        username,
        password,
        jwt.StandardClaims{
            ExpiresAt: expireTime.Unix(),
            Issuer: "gin-blog",
        },
    }
    //
    tokenClaims:=jwt.NewWithClaims(jwt.SigningMethodHS256,claims)
    token,err:=tokenClaims.SignedString(jwtSecret)

    return token,err
}


// 验证token的函数
func ParseToken(token string)(*Claims,error){
    tokenClaims,err:=jwt.ParseWithClaims(token,&Claims{},func(token *jwt.Token)(interface{},error){
        return jwtSecret,nil
    })

    if tokenClaims!=nil{
        if claims,ok:=tokenClaims.Claims.(*Claims);ok && tokenClaims.Valid{
            return claims,nil
        }
    }
    //
    return nil,err
}

最简单的main函数调用

package main

import (
    "fmt"
    jwt "go-gin-example2/pkg/jwt"
    "time"
)

func main() {

    token,_:=jwt.GenerateToken("xingye","123456")
    fmt.Println("生成的token:",token)
    claim,err:=jwt.ParseToken(token)
    if err!=nil {
        fmt.Println("解析token出现错误:",err)
    }else if time.Now().Unix() > claim.ExpiresAt {
        fmt.Println("时间超时")
    }else {
        fmt.Println("username:",claim.Username)
        fmt.Println("password:",claim.Password)
    }

}


结果:

生成的token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Inhpbmd5ZSIsInBhc3N3b3JkIjoiMTIzNDU2IiwiZXhwIjoxNjA2MzAwOTQ4LCJpc3MiOiJnaW4tYmxvZyJ9.Nv6e46XYoKfRjlgCBYnajB_CIRzZKepf09cw6KP3kck
username: xingye
password: 123456

在gin框架中使用jwt

编写中间件,实际就是对token进行验证

package jwt

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "go-gin-example/pkg/e"
    "go-gin-example/pkg/util"
    "net/http"
    "time"
)
// Gin的中间件
func JWT() gin.HandlerFunc {
    return func(c *gin.Context) {
        var code int
        var data interface{}

        code=e.SUCCESS
        token:=c.Query("token")
        if token==""{
            code=e.INVALID_PARAMS
        }else{
            claims,err:=util.ParseToken(token)
            fmt.Println("解析出来的claims:",claims)
            fmt.Println("解析出来的err:",err)
            if err!=nil{
                code=e.ERROR_AUTH_CHECK_TOKEN_FAIL
            }else if time.Now().Unix() > claims.ExpiresAt{
                code=e.ERROR_AUTH_CHECK_TOKEN_TIMEOUT
            }
        }
        //
        if code!=e.SUCCESS{
            c.JSON(http.StatusUnauthorized,gin.H{
                "code":code,
                "msg":e.GetMsg(code),
                "data":data,
            })
            //
            c.Abort()
            return
        }

        c.Next()
    }
}

在路由中添加中间价,这样每次访问的时候都会先进行token的验证

apiv1:=r.Group("/api/v1")
apiv1.Use(jwt.JWT()) // 在这里添加中间件,每次执行都会先走这里进行token验证

你可能感兴趣的:(go使用JWT进行身份验证)