package auth
|
|
import (
|
"encoding/json"
|
jwtLib "github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go/request"
|
"github.com/gin-gonic/gin"
|
"net/http"
|
"strings"
|
"time"
|
)
|
|
type jwtAuthManager struct {
|
secret string
|
expire time.Duration
|
alg string
|
}
|
|
func NewJwtAuthDriver() *jwtAuthManager {
|
return &jwtAuthManager{
|
secret: TokenKey,
|
expire: time.Hour * 8,
|
alg: "HS256",
|
}
|
}
|
|
func (jwtAuth *jwtAuthManager) Check(c *gin.Context) bool {
|
token := c.Request.Header.Get("Authorization")
|
b := "Bearer "
|
if !strings.Contains(token, b) {
|
return false
|
}
|
t := strings.Split(token, b)
|
if len(t) < 2 {
|
return false
|
}
|
var keyFunc = func(token *jwtLib.Token) (interface{}, error) {
|
b := []byte(jwtAuth.secret)
|
return b, nil
|
}
|
authJwtToken, err := request.ParseFromRequest(c.Request, request.OAuth2Extractor, keyFunc)
|
if err != nil {
|
return false
|
}
|
|
c.Set("User", map[string]interface{}{
|
"token": authJwtToken,
|
})
|
|
return authJwtToken.Valid
|
}
|
|
func (jwtAuth *jwtAuthManager) Decode(tokenStr string) (bool,map[string]interface{}) {
|
tokenStr = strings.Replace(tokenStr, "Bearer ", "", -1)
|
if tokenStr != "" {
|
jwtToken, err := jwtLib.Parse(tokenStr, func(token *jwtLib.Token) (interface{}, error) {
|
b := []byte(jwtAuth.secret)
|
return b, nil
|
})
|
if err == nil {
|
if claims, ok := jwtToken.Claims.(jwtLib.MapClaims); ok && jwtToken.Valid {
|
var user map[string]interface{}
|
if err := json.Unmarshal([]byte(claims["user"].(string)), &user); err == nil {
|
return true, user
|
}
|
}
|
}
|
}
|
return false, nil
|
}
|
|
func (jwtAuth *jwtAuthManager) RefreshToken(tokenStr string) (bool,string,string) {
|
tokenStr = strings.Replace(tokenStr, "Bearer ", "", -1)
|
if tokenStr != "" {
|
jwtToken, err := jwtLib.Parse(tokenStr, func(token *jwtLib.Token) (interface{}, error) {
|
b := []byte(jwtAuth.secret)
|
return b, nil
|
})
|
if err == nil {
|
if claims, ok := jwtToken.Claims.(jwtLib.MapClaims); ok && jwtToken.Valid {
|
var user map[string]interface{}
|
if err := json.Unmarshal([]byte(claims["user"].(string)), &user); err == nil {
|
//生成一个新的token和refresh_token值
|
userStr, _ := json.Marshal(user)
|
jwtToken.Claims = jwtLib.MapClaims{
|
"user": string(userStr),
|
"exp": time.Now().Add(jwtAuth.expire).Unix(),
|
}
|
token,e1 := jwtToken.SignedString([]byte(jwtAuth.secret))
|
jwtToken.Claims = jwtLib.MapClaims{
|
"user": string(userStr),
|
"exp": time.Now().Add(jwtAuth.expire + time.Hour * 4).Unix(),
|
}
|
refreshToken,e2 := jwtToken.SignedString([]byte(jwtAuth.secret))
|
if e1 ==nil && e2 == nil {
|
return true, token, refreshToken
|
}
|
}
|
}
|
}
|
}
|
return false,"",""
|
}
|
|
func (jwtAuth *jwtAuthManager) User(c *gin.Context) map[string]interface{} {
|
var jwtToken *jwtLib.Token
|
if jwtUser, exist := c.Get("User"); !exist {
|
tokenStr := strings.Replace(c.Request.Header.Get("Authorization"), "Bearer ", "", -1)
|
if tokenStr == "" {
|
return nil
|
}
|
var err error
|
jwtToken, err = jwtLib.Parse(tokenStr, func(token *jwtLib.Token) (interface{}, error) {
|
b := []byte(jwtAuth.secret)
|
return b, nil
|
})
|
if err != nil {
|
return nil
|
}
|
} else {
|
jwtToken = jwtUser.(map[string]interface{})["token"].(*jwtLib.Token)
|
}
|
if claims, ok := jwtToken.Claims.(jwtLib.MapClaims); ok && jwtToken.Valid {
|
var user map[string]interface{}
|
if err := json.Unmarshal([]byte(claims["user"].(string)), &user); err != nil {
|
return nil
|
}
|
c.Set("User", map[string]interface{}{
|
"token": jwtToken,
|
"user": user,
|
})
|
return user
|
} else {
|
return nil
|
}
|
}
|
|
func (jwtAuth *jwtAuthManager) Login(http *http.Request, w http.ResponseWriter, user map[string]interface{}) (bool,string,string) {
|
|
jwtToken := jwtLib.New(jwtLib.GetSigningMethod(jwtAuth.alg))
|
|
userStr, _ := json.Marshal(user)
|
jwtToken.Claims = jwtLib.MapClaims{
|
"user": string(userStr),
|
"exp": time.Now().Add(jwtAuth.expire).Unix(),
|
}
|
token,e1 := jwtToken.SignedString([]byte(jwtAuth.secret))
|
jwtToken.Claims = jwtLib.MapClaims{
|
"user": string(userStr),
|
"exp": time.Now().Add(jwtAuth.expire + time.Hour * 4).Unix(),
|
}
|
refreshToken,e2 := jwtToken.SignedString([]byte(jwtAuth.secret))
|
if e1 ==nil && e2 ==nil {
|
return true, token, refreshToken
|
}
|
return false, "", ""
|
}
|
|
func (jwtAuth *jwtAuthManager) Logout(http *http.Request, w http.ResponseWriter) bool {
|
|
return true
|
}
|