Skip to content

Commit

Permalink
添加token刷新
Browse files Browse the repository at this point in the history
  • Loading branch information
carlo committed Jun 25, 2020
1 parent 64ff48c commit fba9bb7
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
gateway (协议)
----------------------------------
login | logic
auth | logic
----------------------------------
```
3 changes: 2 additions & 1 deletion common/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ var (
PARAM_ERROR = errors.New("param is error")
NOT_FOUND_ERROR = errors.New("not found")
SERVICE_ERROR = errors.New("服务器错误")
AUTH_ERR = errors.New("认证失败")
AUTH_ERROR = errors.New("认证失败")
TOKEN_INVALID = errors.New("token is invalid")
//PARAM_ERROR = engine.NewResponseError(ERROR_PARAM_ERROR, "param is error")
//MYSQL_PARAM_ERROR = engine.NewResponseError(ERROR_PARAM_ERROR, "sql param is error")
)
Expand Down
16 changes: 16 additions & 0 deletions endpoint/v1/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func AuthV1Router(parentRoute gin.IRouter) {
end := NewAuth()
router.POST("/login",middleware.Jwt(),end.Login)
router.POST("/logout",end.Logout)
router.POST("/token/refresh",end.TokenRefresh)
}

type auth struct {
Expand Down Expand Up @@ -42,4 +43,19 @@ func (a *auth) Login(c *gin.Context) {

func (a auth) Logout(c *gin.Context) {

}

func (a auth) TokenRefresh(c *gin.Context) {
var req model.AuthTokenRefresh
if err := c.Bind(&req); err != nil {
common.GinJsonRespErr(c,common.PARAM_ERROR)
return
}

ret,err := a.service.TokenRefresh(&req)
if err != nil {
common.GinJsonRespErr(c,err)
return
}
common.GinJsonResp(c,ret)
}
80 changes: 63 additions & 17 deletions middleware/jwt.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package middleware

import (
"fmt"
"errors"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"github.com/spf13/cast"
"github.com/wudaoluo/golog"
"github.com/wudaoluo/sonic/common"
"github.com/wudaoluo/sonic/model"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"errors"
)
/*
Playload(载荷又称为Claim)
Expand All @@ -20,6 +19,7 @@ exp: 过期时间
nbf: 生效时间
iat: 签发时间
jti: 唯一身份标识
ref: 刷新token
HMACSHA256(
base64UrlEncode(header) + "." +
Expand All @@ -32,11 +32,33 @@ const (
TOKEN = "Token"
UID = "uid"
USERNAME = "username"
REFRESH = "ref"
)

type JwtToken struct {
Token string `json:"token"`
TokenRefresh string `json:"token_refresh"`
}

func (j *JwtToken) Gen(user *model.ImUser) error {
tokenStr,err := TokenGenerator(user,false)
if err != nil {
return err
}

j.Token = tokenStr

tokenRefreshStr,err := TokenGenerator(user,true)
if err != nil {
return err
}
j.TokenRefresh = tokenRefreshStr
return nil
}

func Jwt() gin.HandlerFunc {
return func(c *gin.Context) {
user,err := parseToken(c.GetHeader(TOKEN))
user,err := ParseToken(c.GetHeader(TOKEN),false)
if err != nil {
golog.Error("middleware.jwt","func","parseToken","err",err)
return
Expand All @@ -53,21 +75,23 @@ func secret()jwt.Keyfunc{
}


func parseToken(tokenString string)(*model.ImUser,error){
user := &model.ImUser{}
token,err := jwt.Parse(tokenString,secret())
if err != nil{
return nil,err
func ParseToken(tokenString string,refresh bool)(*model.ImUser,error){
token ,err := VerifyToken(tokenString)
if err != nil {
return nil, err
}

claim,ok := token.Claims.(jwt.MapClaims)
if !ok{
err = errors.New("cannot convert claim to mapclaim")
return nil,err
}
//验证token,如果token被修改过则为false
if !token.Valid{
err = errors.New("token is invalid")
return nil,err

user := &model.ImUser{}
if refresh {
if v,ok := claim[REFRESH];ok && !cast.ToBool(v){
return nil, common.TOKEN_INVALID
}
}

if v,ok := claim[UID];ok {
Expand All @@ -81,16 +105,38 @@ func parseToken(tokenString string)(*model.ImUser,error){
return user,nil
}

func TokenGenerator(user *model.ImUser) (string, error) {
func VerifyToken(tokenString string) (*jwt.Token,error){
token,err := jwt.Parse(tokenString,secret())
if err != nil{
golog.Error("VerifyToken","func","jwt.Parse","token",tokenString,"err",err)
return nil,err
}

//验证token,如果token被修改过则为false
if !token.Valid{
err = common.TOKEN_INVALID
golog.Error("VerifyToken","func","token.Valid","token",tokenString,"err",err)
return nil,err
}

return token, nil
}


func TokenGenerator(user *model.ImUser,refresh bool) (string, error) {
jwtConf := common.GetConf().Auth.Jwt
now := time.Now()
expire := now.Add(jwtConf.Timeout*time.Second)

expire := now.Add(jwtConf.Timeout*time.Second)
if refresh {
expire = now.Add(2*jwtConf.Timeout*time.Second)
}
claim := jwt.MapClaims{
UID: user.Uid,
USERNAME: user.Username,
USERNAME: user.Username,
"exp": expire.Unix(),
"iat": now,
REFRESH: refresh,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256,claim)
return token.SignedString([]byte(jwtConf.Key))
Expand Down
4 changes: 4 additions & 0 deletions model/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ type AuthLogin struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}

type AuthTokenRefresh struct {
TokenRefresh string `json:"token_refresh"`
}
28 changes: 23 additions & 5 deletions service/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,38 @@ func (a AuthService) Login(reqData *model.AuthLogin) (interface{},error) {
}

if imUser.Password != reqData.Password {
golog.Error("Login","func","imUser.Password != reqData.Password","err",common.AUTH_ERR)
return nil, common.AUTH_ERR
golog.Error("Login","func","imUser.Password != reqData.Password","err",common.AUTH_ERROR)
return nil, common.AUTH_ERROR
}

//jwt
token,err := middleware.TokenGenerator(imUser)
jwtToken := middleware.JwtToken{}
err = jwtToken.Gen(imUser)
if err != nil {
golog.Error("Login","func","middleware.TokenGenerator","err",err)
golog.Error("Login","func","jwtToken.Gen","err",err)
return nil, common.SERVICE_ERROR
}

return token,nil
return jwtToken,nil
}

func (a AuthService) Logout(reqData interface{}) (interface{},error) {
return nil, nil
}

func (a AuthService) TokenRefresh(reqData *model.AuthTokenRefresh) (interface{},error) {
imUser,err := middleware.ParseToken(reqData.TokenRefresh,true)
if err != nil {
golog.Error("TokenRefresh","func","middleware.ParseToken","err",err)
return nil, err
}
jwtToken := middleware.JwtToken{}
err = jwtToken.Gen(imUser)
if err != nil {
golog.Error("TokenRefresh","func","jwtToken.Gen","err",err)
return nil, common.SERVICE_ERROR
}

return jwtToken,nil

}

0 comments on commit fba9bb7

Please sign in to comment.