- 包引入
github.com/dgrijalva/jwt-go
- utils目录下编写Jwt.go
package utils
import (
// "crypto/md5"
"fmt"
"github.com/astaxie/beego/logs"
// "github.com/3xxx/go-sso/models"
"github.com/astaxie/beego"
// "github.com/astaxie/beego/orm"
"strings"
"time"
"github.com/dgrijalva/jwt-go"
)
const (
KEY string = "JWT-xxxx"
DEFAULT_EXPIRE_SECONDS int64 = 24 * 60 * 60 //设置有效期为 24 小时
DEFAULT_REFRESH_SECONDS int64 = 1 * 60 * 60 //设置刷新时间为过期前 1 小时
)
//使用这个生成token
func CreateToken(userName string, su_id int, app string) (tokenString string, expSeconds int64, expTime int64, refreshTime int64, err error) {
// token := jwt.New(jwt.SigningMethodHS256)
claims := make(jwt.MapClaims)
expTime = time.Now().Add(time.Second * time.Duration(DEFAULT_EXPIRE_SECONDS)).Unix()
refreshTime = expTime - DEFAULT_REFRESH_SECONDS
//添加令牌期限
claims["exp"] = expTime
claims["iat"] = time.Now().Unix()
claims["userName"] = userName
claims["suId"] = su_id
claims["app"] = app
// token.Claims = claims
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err = token.SignedString([]byte(KEY))
if err != nil {
logs.Error("generate json web token failed !! error :", err)
return tokenString, 0, 0, 0, err
}
return tokenString, DEFAULT_EXPIRE_SECONDS, expTime, refreshTime, err
}
// 校验token是否有效 返回参数
func CheckToken(tokenString string) (userName string, err error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
return []byte(KEY), nil
})
if err != nil {
logs.Error(err)
return "", err
}
// token.Valid里已经包含了过期判断
if token != nil && token.Valid {
claims, _ := token.Claims.(jwt.MapClaims)
userName = claims["userName"].(string)
}
return userName, err
}
// update expireAt and returnDoc a new token
//只能在过期之前刷新才可以
func RefreshToken(tokenString string) (string, int64, int64, int64, error) {
token, err := jwt.ParseWithClaims(
tokenString,
jwt.MapClaims{},
func(token *jwt.Token) (interface{}, error) {
return []byte(KEY), nil
})
claims, ok := token.Claims.(jwt.MapClaims)
if !ok || !token.Valid {
return "", 0, 0, 0, err
}
expTime := time.Now().Add(time.Second * time.Duration(DEFAULT_EXPIRE_SECONDS)).Unix()
refreshTime := expTime - DEFAULT_REFRESH_SECONDS
//添加令牌期限
newClaims := jwt.MapClaims{
"exp": expTime,
"iat": time.Now().Unix(),
"userName": claims["userName"].(string),
"suId": claims["suId"],
"app": claims["app"],
}
// generate new token with new claims
newToken := jwt.NewWithClaims(jwt.SigningMethodHS256, newClaims)
tokenStr, err := newToken.SignedString([]byte(KEY))
if err != nil {
logs.Error("generate new fresh json web token failed !! error :", err)
return "", 0, 0, 0, err
}
return tokenStr, DEFAULT_EXPIRE_SECONDS, expTime, refreshTime, err
}
// ParseToken parse JWT token in http header.
func ParseToken(authString string) (t *jwt.Token, err error) {
kv := strings.Split(authString, " ")
if len(kv) != 2 || kv[0] != "Bearer" {
logs.Error("AuthString invalid:", authString)
return nil, err
}
tokenString := kv[1]
// Parse token
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(KEY), nil
})
if err != nil {
logs.Error("Parse token:", err)
if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
// That's not even a token
return nil, err
} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
// Token is either expired or not active yet
return nil, err
} else {
// Couldn't handle this token
return nil, err
}
} else {
// Couldn't handle this token
return nil, err
}
}
if !token.Valid {
beego.Error("Token invalid:", tokenString)
return token, err
}
return token, nil
}
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。