|
|
@@ -1,591 +0,0 @@
|
|
|
-package gtoken
|
|
|
-
|
|
|
-import (
|
|
|
- "context"
|
|
|
- "errors"
|
|
|
- "fmt"
|
|
|
- "github.com/gogf/gf/v2/crypto/gaes"
|
|
|
- "github.com/gogf/gf/v2/crypto/gmd5"
|
|
|
- "github.com/gogf/gf/v2/encoding/gbase64"
|
|
|
- "github.com/gogf/gf/v2/frame/g"
|
|
|
- "github.com/gogf/gf/v2/net/ghttp"
|
|
|
- "github.com/gogf/gf/v2/os/gtime"
|
|
|
- "github.com/gogf/gf/v2/text/gstr"
|
|
|
- "github.com/gogf/gf/v2/util/gconv"
|
|
|
- "github.com/gogf/gf/v2/util/grand"
|
|
|
- "net/http"
|
|
|
- "strings"
|
|
|
-)
|
|
|
-
|
|
|
-var GFToken *GfToken
|
|
|
-
|
|
|
-// GfToken gtoken结构体
|
|
|
-type GfToken struct {
|
|
|
- // GoFrame server name
|
|
|
- ServerName string
|
|
|
- // 缓存模式 1 gcache 2 gredis 默认1
|
|
|
- CacheMode int8
|
|
|
- // 缓存key
|
|
|
- CacheKey string
|
|
|
- // 超时时间 默认10天(毫秒)
|
|
|
- Timeout int
|
|
|
- // 缓存刷新时间 默认为超时时间的一半(毫秒)
|
|
|
- MaxRefresh int
|
|
|
- // Token分隔符
|
|
|
- TokenDelimiter string
|
|
|
- // Token加密key
|
|
|
- EncryptKey []byte
|
|
|
- // 认证失败中文提示
|
|
|
- AuthFailMsg string
|
|
|
- // 是否支持多端登录,默认false
|
|
|
- MultiLogin bool
|
|
|
- // 是否是全局认证,兼容历史版本,已废弃
|
|
|
- GlobalMiddleware bool
|
|
|
- // 中间件类型 1 GroupMiddleware 2 BindMiddleware 3 GlobalMiddleware
|
|
|
- MiddlewareType uint
|
|
|
-
|
|
|
- // 登录路径
|
|
|
- LoginPath string
|
|
|
- // 登录验证方法 return userKey 用户标识 如果userKey为空,结束执行
|
|
|
- LoginBeforeFunc func(r *ghttp.Request) (string, interface{})
|
|
|
- // 登录返回方法
|
|
|
- LoginAfterFunc func(r *ghttp.Request, respData Resp)
|
|
|
- // 登出地址
|
|
|
- LogoutPath string
|
|
|
- // 登出验证方法 return true 继续执行,否则结束执行
|
|
|
- LogoutBeforeFunc func(r *ghttp.Request) bool
|
|
|
- // 登出返回方法
|
|
|
- LogoutAfterFunc func(r *ghttp.Request, respData Resp)
|
|
|
-
|
|
|
- // 拦截地址
|
|
|
- AuthPaths g.SliceStr
|
|
|
- // 拦截排除地址
|
|
|
- AuthExcludePaths g.SliceStr
|
|
|
- // 认证验证方法 return true 继续执行,否则结束执行
|
|
|
- AuthBeforeFunc func(r *ghttp.Request) bool
|
|
|
- // 认证返回方法
|
|
|
- AuthAfterFunc func(r *ghttp.Request, respData Resp)
|
|
|
-}
|
|
|
-
|
|
|
-// Login 登录
|
|
|
-func (m *GfToken) Login(r *ghttp.Request) {
|
|
|
- userKey, data := m.LoginBeforeFunc(r)
|
|
|
- if userKey == "" {
|
|
|
- g.Log().Error(r.Context(), msgLog(MsgErrUserKeyEmpty))
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- if m.MultiLogin {
|
|
|
- // 支持多端重复登录,返回相同token
|
|
|
- userCacheResp := m.getToken(r.Context(), userKey)
|
|
|
- if userCacheResp.Success() {
|
|
|
- respToken := m.EncryptToken(r.Context(), userKey, userCacheResp.GetString(KeyUuid))
|
|
|
- m.LoginAfterFunc(r, respToken)
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 生成token
|
|
|
- respToken := m.genToken(r.Context(), userKey, data)
|
|
|
- m.LoginAfterFunc(r, respToken)
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-// Logout 登出
|
|
|
-func (m *GfToken) Logout(r *ghttp.Request) {
|
|
|
- if !m.LogoutBeforeFunc(r) {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // 获取请求token
|
|
|
- respData := m.getRequestToken(r)
|
|
|
- if respData.Success() {
|
|
|
- // 删除token
|
|
|
- m.RemoveToken(r.Context(), respData.DataString())
|
|
|
- }
|
|
|
-
|
|
|
- m.LogoutAfterFunc(r, respData)
|
|
|
-}
|
|
|
-
|
|
|
-// AuthMiddleware 认证拦截
|
|
|
-func (m *GfToken) authMiddleware(r *ghttp.Request) {
|
|
|
- urlPath := r.URL.Path
|
|
|
- if !m.AuthPath(r.Context(), urlPath) {
|
|
|
- // 如果不需要认证,继续
|
|
|
- r.Middleware.Next()
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // 不需要认证,直接下一步
|
|
|
- if !m.AuthBeforeFunc(r) {
|
|
|
- r.Middleware.Next()
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // 获取请求token
|
|
|
- tokenResp := m.getRequestToken(r)
|
|
|
- if tokenResp.Success() {
|
|
|
- // 验证token
|
|
|
- tokenResp = m.validToken(r.Context(), tokenResp.DataString())
|
|
|
- }
|
|
|
-
|
|
|
- m.AuthAfterFunc(r, tokenResp)
|
|
|
-}
|
|
|
-
|
|
|
-// GetTokenData 通过token获取对象
|
|
|
-func (m *GfToken) GetTokenData(r *ghttp.Request) Resp {
|
|
|
- respData := m.getRequestToken(r)
|
|
|
- if respData.Success() {
|
|
|
- // 验证token
|
|
|
- respData = m.validToken(r.Context(), respData.DataString())
|
|
|
- }
|
|
|
-
|
|
|
- return respData
|
|
|
-}
|
|
|
-
|
|
|
-// AuthPath 判断路径是否需要进行认证拦截
|
|
|
-// return true 需要认证
|
|
|
-func (m *GfToken) AuthPath(ctx context.Context, urlPath string) bool {
|
|
|
- // 去除后斜杠
|
|
|
- if strings.HasSuffix(urlPath, "/") {
|
|
|
- urlPath = gstr.SubStr(urlPath, 0, len(urlPath)-1)
|
|
|
- }
|
|
|
- // 分组拦截,登录接口不拦截
|
|
|
- if m.MiddlewareType == MiddlewareTypeGroup {
|
|
|
- if (m.LoginPath != "" && gstr.HasSuffix(urlPath, m.LoginPath)) ||
|
|
|
- (m.LogoutPath != "" && gstr.HasSuffix(urlPath, m.LogoutPath)) {
|
|
|
- return false
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 全局处理,认证路径拦截处理
|
|
|
- if m.MiddlewareType == MiddlewareTypeGlobal {
|
|
|
- var authFlag bool
|
|
|
- for _, authPath := range m.AuthPaths {
|
|
|
- tmpPath := authPath
|
|
|
- if strings.HasSuffix(tmpPath, "/*") {
|
|
|
- tmpPath = gstr.SubStr(tmpPath, 0, len(tmpPath)-2)
|
|
|
- }
|
|
|
- if gstr.HasPrefix(urlPath, tmpPath) {
|
|
|
- authFlag = true
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if !authFlag {
|
|
|
- // 拦截路径不匹配
|
|
|
- return false
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 排除路径处理,到这里nextFlag为true
|
|
|
- for _, excludePath := range m.AuthExcludePaths {
|
|
|
- tmpPath := excludePath
|
|
|
- // 前缀匹配
|
|
|
- if strings.HasSuffix(tmpPath, "/*") {
|
|
|
- tmpPath = gstr.SubStr(tmpPath, 0, len(tmpPath)-2)
|
|
|
- if gstr.HasPrefix(urlPath, tmpPath) {
|
|
|
- // 前缀匹配不拦截
|
|
|
- return false
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 全路径匹配
|
|
|
- if strings.HasSuffix(tmpPath, "/") {
|
|
|
- tmpPath = gstr.SubStr(tmpPath, 0, len(tmpPath)-1)
|
|
|
- }
|
|
|
- if urlPath == tmpPath {
|
|
|
- // 全路径匹配不拦截
|
|
|
- return false
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return true
|
|
|
-}
|
|
|
-
|
|
|
-// getRequestToken 返回请求Token
|
|
|
-func (m *GfToken) getRequestToken(r *ghttp.Request) Resp {
|
|
|
- authHeader := r.Header.Get("Authorization")
|
|
|
- if authHeader != "" {
|
|
|
- parts := strings.SplitN(authHeader, " ", 2)
|
|
|
- if !(len(parts) == 2 && parts[0] == "Bearer") {
|
|
|
- g.Log().Warning(r.Context(), msgLog(MsgErrAuthHeader, authHeader))
|
|
|
- return Unauthorized(fmt.Sprintf(MsgErrAuthHeader, authHeader), "")
|
|
|
- } else if parts[1] == "" {
|
|
|
- g.Log().Warning(r.Context(), msgLog(MsgErrAuthHeader, authHeader))
|
|
|
- return Unauthorized(fmt.Sprintf(MsgErrAuthHeader, authHeader), "")
|
|
|
- }
|
|
|
-
|
|
|
- return Succ(parts[1])
|
|
|
- }
|
|
|
-
|
|
|
- authHeader = r.Get(KeyToken).String()
|
|
|
- if authHeader == "" {
|
|
|
- return Unauthorized(MsgErrTokenEmpty, "")
|
|
|
- }
|
|
|
- return Succ(authHeader)
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-// genToken 生成Token
|
|
|
-func (m *GfToken) genToken(ctx context.Context, userKey string, data interface{}) Resp {
|
|
|
- token := m.EncryptToken(ctx, userKey, "")
|
|
|
- if !token.Success() {
|
|
|
- return token
|
|
|
- }
|
|
|
-
|
|
|
- cacheKey := m.CacheKey + userKey
|
|
|
- userCache := g.Map{
|
|
|
- KeyUserKey: userKey,
|
|
|
- KeyUuid: token.GetString(KeyUuid),
|
|
|
- KeyData: data,
|
|
|
- KeyCreateTime: gtime.Now().TimestampMilli(),
|
|
|
- KeyRefreshTime: gtime.Now().TimestampMilli() + gconv.Int64(m.MaxRefresh),
|
|
|
- }
|
|
|
-
|
|
|
- cacheResp := m.setCache(ctx, cacheKey, userCache)
|
|
|
- if !cacheResp.Success() {
|
|
|
- return cacheResp
|
|
|
- }
|
|
|
-
|
|
|
- return token
|
|
|
-}
|
|
|
-
|
|
|
-// validToken 验证Token
|
|
|
-func (m *GfToken) validToken(ctx context.Context, token string) Resp {
|
|
|
- if token == "" {
|
|
|
- return Unauthorized(MsgErrTokenEmpty, "")
|
|
|
- }
|
|
|
-
|
|
|
- decryptToken := m.DecryptToken(ctx, token)
|
|
|
- if !decryptToken.Success() {
|
|
|
- return decryptToken
|
|
|
- }
|
|
|
-
|
|
|
- userKey := decryptToken.GetString(KeyUserKey)
|
|
|
- uuid := decryptToken.GetString(KeyUuid)
|
|
|
-
|
|
|
- userCacheResp := m.getToken(ctx, userKey)
|
|
|
- if !userCacheResp.Success() {
|
|
|
- return userCacheResp
|
|
|
- }
|
|
|
-
|
|
|
- if uuid != userCacheResp.GetString(KeyUuid) {
|
|
|
- g.Log().Debug(ctx, msgLog(MsgErrAuthUuid)+", decryptToken:"+decryptToken.Json()+" cacheValue:"+gconv.String(userCacheResp.Data))
|
|
|
- return Unauthorized(MsgErrAuthUuid, "")
|
|
|
- }
|
|
|
-
|
|
|
- return userCacheResp
|
|
|
-}
|
|
|
-
|
|
|
-// getToken 通过userKey获取Token
|
|
|
-func (m *GfToken) getToken(ctx context.Context, userKey string) Resp {
|
|
|
- cacheKey := m.CacheKey + userKey
|
|
|
-
|
|
|
- userCacheResp := m.getCache(ctx, cacheKey)
|
|
|
- if !userCacheResp.Success() {
|
|
|
- return userCacheResp
|
|
|
- }
|
|
|
- userCache := gconv.Map(userCacheResp.Data)
|
|
|
-
|
|
|
- nowTime := gtime.Now().TimestampMilli()
|
|
|
- refreshTime := userCache[KeyRefreshTime]
|
|
|
-
|
|
|
- // 需要进行缓存超时时间刷新
|
|
|
- if gconv.Int64(refreshTime) == 0 || nowTime > gconv.Int64(refreshTime) {
|
|
|
- userCache[KeyCreateTime] = gtime.Now().TimestampMilli()
|
|
|
- userCache[KeyRefreshTime] = gtime.Now().TimestampMilli() + gconv.Int64(m.MaxRefresh)
|
|
|
- return m.setCache(ctx, cacheKey, userCache)
|
|
|
- }
|
|
|
-
|
|
|
- return Succ(userCache)
|
|
|
-}
|
|
|
-
|
|
|
-// RemoveToken 删除Token
|
|
|
-func (m *GfToken) RemoveToken(ctx context.Context, token string) Resp {
|
|
|
- decryptToken := m.DecryptToken(ctx, token)
|
|
|
- if !decryptToken.Success() {
|
|
|
- return decryptToken
|
|
|
- }
|
|
|
-
|
|
|
- cacheKey := m.CacheKey + decryptToken.GetString(KeyUserKey)
|
|
|
- return m.removeCache(ctx, cacheKey)
|
|
|
-}
|
|
|
-
|
|
|
-// EncryptToken token加密方法
|
|
|
-func (m *GfToken) EncryptToken(ctx context.Context, userKey string, uuid string) Resp {
|
|
|
- if userKey == "" {
|
|
|
- return Fail(MsgErrUserKeyEmpty)
|
|
|
- }
|
|
|
-
|
|
|
- if uuid == "" {
|
|
|
- // 重新生成uuid
|
|
|
- newUuid, err := gmd5.Encrypt(grand.Letters(10))
|
|
|
- if err != nil {
|
|
|
- g.Log().Error(ctx, msgLog(MsgErrAuthUuid), err)
|
|
|
- return Error(MsgErrAuthUuid)
|
|
|
- }
|
|
|
- uuid = newUuid
|
|
|
- }
|
|
|
-
|
|
|
- tokenStr := userKey + m.TokenDelimiter + uuid
|
|
|
-
|
|
|
- token, err := gaes.Encrypt([]byte(tokenStr), m.EncryptKey)
|
|
|
- if err != nil {
|
|
|
- g.Log().Error(ctx, msgLog(MsgErrTokenEncrypt), tokenStr, err)
|
|
|
- return Error(MsgErrTokenEncrypt)
|
|
|
- }
|
|
|
-
|
|
|
- return Succ(g.Map{
|
|
|
- KeyUserKey: userKey,
|
|
|
- KeyUuid: uuid,
|
|
|
- KeyToken: gbase64.EncodeToString(token),
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-// DecryptToken token解密方法
|
|
|
-func (m *GfToken) DecryptToken(ctx context.Context, token string) Resp {
|
|
|
- if token == "" {
|
|
|
- return Fail(MsgErrTokenEmpty)
|
|
|
- }
|
|
|
-
|
|
|
- token64, err := gbase64.Decode([]byte(token))
|
|
|
- if err != nil {
|
|
|
- g.Log().Error(ctx, msgLog(MsgErrTokenDecode), token, err)
|
|
|
- return Error(MsgErrTokenDecode)
|
|
|
- }
|
|
|
- decryptToken, err2 := gaes.Decrypt(token64, m.EncryptKey)
|
|
|
- if err2 != nil {
|
|
|
- g.Log().Error(ctx, msgLog(MsgErrTokenEncrypt), token, err2)
|
|
|
- return Error(MsgErrTokenEncrypt)
|
|
|
- }
|
|
|
- tokenArray := gstr.Split(string(decryptToken), m.TokenDelimiter)
|
|
|
- if len(tokenArray) < 2 {
|
|
|
- g.Log().Error(ctx, msgLog(MsgErrTokenLen), token)
|
|
|
- return Error(MsgErrTokenLen)
|
|
|
- }
|
|
|
-
|
|
|
- return Succ(g.Map{
|
|
|
- KeyUserKey: tokenArray[0],
|
|
|
- KeyUuid: tokenArray[1],
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-// InitConfig 初始化配置信息
|
|
|
-func (m *GfToken) InitConfig() bool {
|
|
|
- if m.CacheMode == 0 {
|
|
|
- m.CacheMode = CacheModeCache
|
|
|
- }
|
|
|
-
|
|
|
- if m.CacheKey == "" {
|
|
|
- m.CacheKey = DefaultCacheKey
|
|
|
- }
|
|
|
-
|
|
|
- if m.Timeout == 0 {
|
|
|
- m.Timeout = DefaultTimeout
|
|
|
- }
|
|
|
-
|
|
|
- if m.MaxRefresh == 0 {
|
|
|
- m.MaxRefresh = m.Timeout / 2
|
|
|
- }
|
|
|
-
|
|
|
- if m.TokenDelimiter == "" {
|
|
|
- m.TokenDelimiter = DefaultTokenDelimiter
|
|
|
- }
|
|
|
-
|
|
|
- if len(m.EncryptKey) == 0 {
|
|
|
- m.EncryptKey = []byte(DefaultEncryptKey)
|
|
|
- }
|
|
|
-
|
|
|
- if m.AuthFailMsg == "" {
|
|
|
- m.AuthFailMsg = DefaultAuthFailMsg
|
|
|
- }
|
|
|
-
|
|
|
- // 设置中间件模式,未设置说明历史版本,通过GlobalMiddleware兼容
|
|
|
- if m.MiddlewareType == 0 {
|
|
|
- if m.GlobalMiddleware {
|
|
|
- m.MiddlewareType = MiddlewareTypeGlobal
|
|
|
- } else {
|
|
|
- m.MiddlewareType = MiddlewareTypeBind
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if m.LoginAfterFunc == nil {
|
|
|
- m.LoginAfterFunc = func(r *ghttp.Request, respData Resp) {
|
|
|
- if !respData.Success() {
|
|
|
- r.Response.WriteJson(respData)
|
|
|
- } else {
|
|
|
- r.Response.WriteJson(Succ(g.Map{
|
|
|
- KeyToken: respData.GetString(KeyToken),
|
|
|
- }))
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if m.LogoutBeforeFunc == nil {
|
|
|
- m.LogoutBeforeFunc = func(r *ghttp.Request) bool {
|
|
|
- return true
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if m.LogoutAfterFunc == nil {
|
|
|
- m.LogoutAfterFunc = func(r *ghttp.Request, respData Resp) {
|
|
|
- if respData.Success() {
|
|
|
- r.Response.WriteJson(Succ(MsgLogoutSucc))
|
|
|
- } else {
|
|
|
- r.Response.WriteJson(respData)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if m.AuthBeforeFunc == nil {
|
|
|
- m.AuthBeforeFunc = func(r *ghttp.Request) bool {
|
|
|
- // 静态页面不拦截
|
|
|
- if r.IsFileRequest() {
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- return true
|
|
|
- }
|
|
|
- }
|
|
|
- if m.AuthAfterFunc == nil {
|
|
|
- m.AuthAfterFunc = func(r *ghttp.Request, respData Resp) {
|
|
|
- if respData.Success() {
|
|
|
- r.Middleware.Next()
|
|
|
- } else {
|
|
|
- var params map[string]interface{}
|
|
|
- if r.Method == http.MethodGet {
|
|
|
- params = r.GetMap()
|
|
|
- } else if r.Method == http.MethodPost {
|
|
|
- params = r.GetMap()
|
|
|
- } else {
|
|
|
- r.Response.Writeln(MsgErrReqMethod)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- no := gconv.String(gtime.TimestampMilli())
|
|
|
-
|
|
|
- g.Log().Warning(r.Context(), fmt.Sprintf("[AUTH_%s][url:%s][params:%s][data:%s]",
|
|
|
- no, r.URL.Path, params, respData.Json()))
|
|
|
- respData.Msg = m.AuthFailMsg
|
|
|
- r.Response.WriteJson(respData)
|
|
|
- r.ExitAll()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return true
|
|
|
-}
|
|
|
-
|
|
|
-// Start 启动
|
|
|
-func (m *GfToken) Start() error {
|
|
|
- if !m.InitConfig() {
|
|
|
- return errors.New(MsgErrInitFail)
|
|
|
- }
|
|
|
-
|
|
|
- ctx := context.Background()
|
|
|
- g.Log().Info(ctx, msgLog("[params:"+m.String()+"]start... "))
|
|
|
-
|
|
|
- s := g.Server(m.ServerName)
|
|
|
-
|
|
|
- // 缓存模式
|
|
|
- if m.CacheMode > CacheModeFile {
|
|
|
- g.Log().Error(ctx, msgLog(MsgErrNotSet, "CacheMode"))
|
|
|
- return errors.New(fmt.Sprintf(MsgErrNotSet, "CacheMode"))
|
|
|
- }
|
|
|
-
|
|
|
- // 初始化文件缓存
|
|
|
- if m.CacheMode == 3 {
|
|
|
- m.initFileCache(ctx)
|
|
|
- }
|
|
|
-
|
|
|
- // 认证拦截器
|
|
|
- if m.AuthPaths == nil {
|
|
|
- g.Log().Error(ctx, msgLog(MsgErrNotSet, "AuthPaths"))
|
|
|
- return errors.New(fmt.Sprintf(MsgErrNotSet, "AuthPaths"))
|
|
|
- }
|
|
|
-
|
|
|
- // 是否是全局拦截
|
|
|
- if m.MiddlewareType == MiddlewareTypeGlobal {
|
|
|
- s.BindMiddlewareDefault(m.authMiddleware)
|
|
|
- } else {
|
|
|
- for _, authPath := range m.AuthPaths {
|
|
|
- tmpPath := authPath
|
|
|
- if !strings.HasSuffix(authPath, "/*") {
|
|
|
- tmpPath += "/*"
|
|
|
- }
|
|
|
- s.BindMiddleware(tmpPath, m.authMiddleware)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 登录
|
|
|
- if m.LoginPath == "" {
|
|
|
- g.Log().Error(ctx, msgLog(MsgErrNotSet, "LoginPath"))
|
|
|
- return errors.New(fmt.Sprintf(MsgErrNotSet, "LoginPath"))
|
|
|
- }
|
|
|
- if m.LoginBeforeFunc == nil {
|
|
|
- g.Log().Error(ctx, msgLog(MsgErrNotSet, "LoginBeforeFunc"))
|
|
|
- return errors.New(fmt.Sprintf(MsgErrNotSet, "LoginBeforeFunc"))
|
|
|
- }
|
|
|
- s.BindHandler(m.LoginPath, m.Login)
|
|
|
-
|
|
|
- // 登出
|
|
|
- if m.LogoutPath == "" {
|
|
|
- g.Log().Error(ctx, msgLog(MsgErrNotSet, "LogoutPath"))
|
|
|
- return errors.New(fmt.Sprintf(MsgErrNotSet, "LogoutPath"))
|
|
|
- }
|
|
|
- s.BindHandler(m.LogoutPath, m.Logout)
|
|
|
-
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-// Stop 结束
|
|
|
-func (m *GfToken) Stop(ctx context.Context) error {
|
|
|
- g.Log().Info(ctx, "[GToken]stop. ")
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-// String token解密方法
|
|
|
-func (m *GfToken) String() string {
|
|
|
- return gconv.String(g.Map{
|
|
|
- // 缓存模式 1 gcache 2 gredis 默认1
|
|
|
- "CacheMode": m.CacheMode,
|
|
|
- "CacheKey": m.CacheKey,
|
|
|
- "Timeout": m.Timeout,
|
|
|
- "TokenDelimiter": m.TokenDelimiter,
|
|
|
- "AuthFailMsg": m.AuthFailMsg,
|
|
|
- "MultiLogin": m.MultiLogin,
|
|
|
- "MiddlewareType": m.MiddlewareType,
|
|
|
- "LoginPath": m.LoginPath,
|
|
|
- "LogoutPath": m.LogoutPath,
|
|
|
- "AuthPaths": gconv.String(m.AuthPaths),
|
|
|
- "AuthExcludePaths": gconv.String(m.AuthExcludePaths),
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-// ValidToken 验证Token
|
|
|
-func (m *GfToken) ValidToken(ctx context.Context, token string) Resp {
|
|
|
- if token == "" {
|
|
|
- return Unauthorized(MsgErrTokenEmpty, "")
|
|
|
- }
|
|
|
-
|
|
|
- decryptToken := m.DecryptToken(ctx, token)
|
|
|
- if !decryptToken.Success() {
|
|
|
- return decryptToken
|
|
|
- }
|
|
|
-
|
|
|
- userKey := decryptToken.GetString(KeyUserKey)
|
|
|
- uuid := decryptToken.GetString(KeyUuid)
|
|
|
-
|
|
|
- userCacheResp := m.getToken(ctx, userKey)
|
|
|
- if !userCacheResp.Success() {
|
|
|
- return userCacheResp
|
|
|
- }
|
|
|
-
|
|
|
- if uuid != userCacheResp.GetString(KeyUuid) {
|
|
|
- g.Log().Debug(ctx, msgLog(MsgErrAuthUuid)+", decryptToken:"+decryptToken.Json()+" cacheValue:"+gconv.String(userCacheResp.Data))
|
|
|
- return Unauthorized(MsgErrAuthUuid, "")
|
|
|
- }
|
|
|
-
|
|
|
- return userCacheResp
|
|
|
-}
|