废话不多说,直接上代码
package main
import (
"github.com/dgrijalva/jwt-go"
"log"
"fmt"
"errors"
"time"
)
// 一些常量
var (
TokenExpired error = errors.New("Token is expired")
TokenNotValidYet error = errors.New("Token not active yet")
TokenMalformed error = errors.New("That's not even a token")
TokenInvalid error = errors.New("Couldn't handle this token:")
SignKey string = "newtrekWang"
hmacSampleSecret string = "xTcDKckjG37IrfRoCs35uEc13mF%vuNYlBM%gLznpVmN6yoEEj1H6F9wpjBfmq7k"
)
type JWT struct {
SigningKey []byte
}
type CustomClaims struct {
Subject int64 `json:"sub"`
Prv string `json:"prv"`
jwt.StandardClaims
}
func NewJWT(secret string) *JWT {
return &JWT{SigningKey:[]byte(secret)}
}
//创建token
func (j *JWT) CreateToken(claims CustomClaims) (string, error) {
token := jwt.New(jwt.SigningMethodHS256)
token.Claims = claims
res, err := token.SignedString(j.SigningKey)
fmt.Println("err:", err)
return res, err
}
//解析token
func (j *JWT) ParseToken(tokenString string) (*CustomClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
log.Panicln("unexpected signing method")
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return j.SigningKey, nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
return claims, nil
}
return nil, TokenInvalid
}
//更新token
func (j *JWT) RefreshToken(tokenString string) (string, error) {
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return j.SigningKey, nil
})
if err != nil {
return "", err
}
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
claims.StandardClaims.ExpiresAt = time.Now().Add(1 * time.Hour).Unix()
return j.CreateToken(*claims)
}
return "", TokenInvalid
}
func (j *JWT) GenerateToken(uid int64) (string,error) {
now := int64(time.Now().Unix())
claims := CustomClaims{
uid,
"23bd5c8949f600adb39e701c400872db7a5976f7", jwt.StandardClaims{
IssuedAt: now,
NotBefore: now - 60,
ExpiresAt: now + 1000,
Issuer: "man",
},
}
token, err := j.CreateToken(claims)
if err != nil {
return "", err
}
return token,nil
}
func main() {
jwt.TimeFunc = time.Now
tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEsInBydiI6IjIzYmQ1Yzg5NDlmNjAwYWRiMzllNzAxYzQwMDg3MmRiN2E1OTc2ZjciLCJleHAiOjE1ODI5NDM1NTEsImlhdCI6MTU4Mjk0MjU1MSwiaXNzIjoibWFuIiwibmJmIjoxNTgyOTQyNDkxfQ.KTP1RWWaHpcPknNTiYeE-iAY9qOJscdJ5r5BbNlYCho"
j := NewJWT(hmacSampleSecret)
// Parse takes the token string and a function for looking up the key. The latter is especially
// useful if you use multiple keys for your application. The standard is to use 'kid' in the
// head of the token to identify which key to use, but the parsed token (head and claims) is provided
// to the callback, providing flexibility.
claims, err := j.ParseToken(tokenString)
if err == nil {
fmt.Printf("user id:%d\n",claims.Subject)
fmt.Printf("%+v\n",claims)
} else {
fmt.Println(err.Error())
}
new_token, err := j.GenerateToken(1)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(new_token)
}
hmacSampleSecret23bd5c8949f600adb39e701c400872db7a5976f7prvSubjectsublast_loginissue atlast_loginlast_login