go JWTによる認証

3486 ワード

まずtokenの生成とtokenの解析の2つの関数を記述します
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