Skip to content

Commit

Permalink
single point login
Browse files Browse the repository at this point in the history
  • Loading branch information
amberzizi committed Jul 4, 2021
1 parent e3f9079 commit ae0b538
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 34 deletions.
45 changes: 32 additions & 13 deletions application/logic/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import (
"errors"
"mygin/application/models"
"mygin/dao/daomysql"
"mygin/dao/daoredis"
"mygin/tools/encryption"
"mygin/tools/ginjwt"
"mygin/tools/randstring"
"mygin/tools/snowflake"
"strconv"
)

//定义自定义error
Expand Down Expand Up @@ -91,6 +93,9 @@ func GenUserJwtToken(p *models.ParamLoginIn) (string, error) {
if err != nil {
return "", err
}
//成功登录 ,保存对应关系到redis 用以单点登录检查
SetAccesstokenByUserID_ForRelation(userinfo.User_id, token)

return token, err
}

Expand All @@ -105,24 +110,38 @@ func GenUserJwtRefreshToken() (string, error) {

//刷新accesstoken
func GetUserNewAccesstoken(p *models.ParamRefreshAccessToken) (string, error) {
token, err := ginjwt.RefreshTokenForNewAccessToken(p.Accesstoken, p.Refreshtoken)
token, user_id, err := ginjwt.RefreshTokenForNewAccessToken(p.Accesstoken, p.Refreshtoken)
if err != nil {
return "", err
}
//成功刷新 刷新accesstoken后 重新为userid绑定
SetAccesstokenByUserID_ForRelation(user_id, token)
return token, err
}

//解析jwttoken
func ParseUserJwtToken(tokenString string) (*models.Userinfopublic, error) {
jwtinfo, err := ginjwt.ParseJwtToken(tokenString)
if err != nil {
return nil, err
}

userinfo, err := daomysql.GetUserInfoByUserId(jwtinfo.User_id)
if err != nil {
return nil, err
}
//从数据库内取出userid对应的accecctoken
func GetOnlineAccesstokenByUserID_ForRelation(user_id int64) (string, error) {
re, err := daoredis.GetAccesstokenByUserID(strconv.FormatInt(user_id, 10))
return re, err
}

return userinfo, err
//设置对应accesstoken
func SetAccesstokenByUserID_ForRelation(user_id int64, atoken string) error {
err := daoredis.SetAccesstokenByUserID(strconv.FormatInt(user_id, 10), atoken)
return err
}

////解析jwttoken
//func ParseUserJwtToken(tokenString string) (*models.Userinfopublic, error) {
// jwtinfo, err := ginjwt.ParseJwtToken(tokenString)
// if err != nil {
// return nil, err
// }
//
// userinfo, err := daomysql.GetUserInfoByUserId(jwtinfo.User_id)
// if err != nil {
// return nil, err
// }
//
// return userinfo, err
//}
15 changes: 15 additions & 0 deletions dao/daoredis/user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package daoredis

//查询
func GetAccesstokenByUserID(user_id string) (string, error) {
rdb := ReturnRedisDb()
n, err := rdb.Get(user_id).Result()
return n, err
}

//设置
func SetAccesstokenByUserID(user_id string, atoken string) error {
rdb := ReturnRedisDb()
err := rdb.Set(user_id, atoken, 0).Err()
return err
}
18 changes: 18 additions & 0 deletions middlewares/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ package middlewares
import (
"errors"
"github.com/gin-gonic/gin"
"mygin/application/logic"
"mygin/application/models"
"mygin/settings"
"mygin/tools/gin_request_response"
"mygin/tools/ginjwt"
"strings"
)

//检查accesstoken 是否过期 是否可解析
//单点登录检查 (1)登录后/使用refreshtoken刷新accesstoken之后 都会在redis存入user_id=>accesstoken
// (2)在此处每次需要鉴权的时候都检查是否userid和token匹配 如不匹配表面token失效 要求重新登录
//auth middleware
func JwtAuthMiddleware() func(c *gin.Context) {
return func(c *gin.Context) {
Expand Down Expand Up @@ -46,6 +50,20 @@ func JwtAuthMiddleware() func(c *gin.Context) {
c.Abort()
return
}

//进行redis上绑定的accesstoken对比 单点登录检查
nowtoken, err := logic.GetOnlineAccesstokenByUserID_ForRelation(mc.User_id)
if err != nil {
gin_request_response.Response(c, settings.ErrorAccessTokenSingleLoginCheck, nil)
c.Abort()
return
}
if nowtoken != parts[1] {
gin_request_response.Response(c, settings.ErrorAccessTokenSingleLoginHavefreshed, nil)
c.Abort()
return
}

c.Set(models.ContextUserIdKey, mc.User_id) //为c上下文对象绑定新参数user_id 使用中间件的路由即可获取
c.Next()

Expand Down
38 changes: 21 additions & 17 deletions settings/code_setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@ package settings

//定义错误码
const (
Codefail = 1000 + iota //"faild"
CodeSuccess //"success",
CodeInvalidParam //"请求参数有误",
CodeCheckPasswordWrong //密码验证输入错误
CodeRegisterFail //注册失败
CodeCheckPasswordThroughWrong //验证密码过程错误
CodePasswordOrUsernameWrong //用户名或密码错误
CodeVerifyWrong //验证码输入错误
CodeUserExist //用户已存在
CodeUserNotExist //用户不存在
CodeServerBusy //服务繁忙
ErrorInvalidToken //无效token
ErrorGenToken //生成token失败
ErrorEmptyToken //无认证token
ErrorFormatToken //token格式错误
ErrorUserNotLogin //用户未登录
ErrorAccessTokenExpiredOutOfTime //accesstoken过期
Codefail = 1000 + iota //"faild"
CodeSuccess //"success",
CodeInvalidParam //"请求参数有误",
CodeCheckPasswordWrong //密码验证输入错误
CodeRegisterFail //注册失败
CodeCheckPasswordThroughWrong //验证密码过程错误
CodePasswordOrUsernameWrong //用户名或密码错误
CodeVerifyWrong //验证码输入错误
CodeUserExist //用户已存在
CodeUserNotExist //用户不存在
CodeServerBusy //服务繁忙
ErrorInvalidToken //无效token
ErrorGenToken //生成token失败
ErrorEmptyToken //无认证token
ErrorFormatToken //token格式错误
ErrorUserNotLogin //用户未登录
ErrorAccessTokenExpiredOutOfTime //accesstoken过期
ErrorAccessTokenSingleLoginCheck //单点登录检查异常-查询异常
ErrorAccessTokenSingleLoginHavefreshed //单点登录检查异常-已有新的登录token-请重新登录
)

var CodeSetting = [...]string{
Expand All @@ -39,4 +41,6 @@ var CodeSetting = [...]string{
1014: "token格式错误",
1015: "用户未登录",
1016: "accesstoken过期",
1017: "单点登录检查异常-查询异常",
1018: "单点登录检查异常-已有新的登录token-请重新登录",
}
9 changes: 5 additions & 4 deletions tools/ginjwt/ginjwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ func ParseJwtToken(tokenString string) (*models.MyJwtInfo, error) {
}

//使用freshtoken 更新 accesstoken
func RefreshTokenForNewAccessToken(aToken, rToken string) (string, error) {
func RefreshTokenForNewAccessToken(aToken, rToken string) (string, int64, error) {
//refresh token 无效直接返回
if _, err := jwt.Parse(rToken,
func(token *jwt.Token) (i interface{}, err error) {
return models.GetJwtTokenKey(), nil
}); err != nil {
return "", err
return "", 0, err
}
//从旧的accesstoken中解析出claims数据
var claims models.MyJwtInfo
Expand All @@ -83,10 +83,11 @@ func RefreshTokenForNewAccessToken(aToken, rToken string) (string, error) {
v, _ := err.(*jwt.ValidationError)
//当accesstoken 是过期错误 并且refreshtoken没过期时就创建并返回一个新的accesstoken
if v.Errors == jwt.ValidationErrorExpired {
return GenJwtToken(claims.Username, claims.User_id)
atoken, err := GenJwtToken(claims.Username, claims.User_id)
return atoken, claims.User_id, err
}
}

//如果解析未出问题 原始accesstoken也未过期 返回原始accesstoken
return aToken, err
return aToken, claims.User_id, err
}

0 comments on commit ae0b538

Please sign in to comment.