代码拉取完成,页面将自动刷新
package jwtauth
import (
"fmt"
"net/http"
"time"
"gitee.com/linxing_3/youye-core/sdk/pkg/jwtauth/user"
"gitee.com/linxing_3/youye-core/sdk/pkg/utils"
"gitee.com/linxing_3/youye-core/storage"
"github.com/gin-gonic/gin"
"github.com/spf13/cast"
)
type GinSessionOption func(*GinSessionAuth)
// 缓存空间
func SessionWithStorage(arg storage.AdapterCache) GinSessionOption {
return func(a *GinSessionAuth) { a.Storage = arg }
}
// 缓存key前缀
func SessionWithPrefixKey(arg string) GinSessionOption {
return func(a *GinSessionAuth) { a.PrefixKey = arg }
}
// 有效期(秒)
func SessionWithExpired(arg int) GinSessionOption {
return func(a *GinSessionAuth) { a.Expired = arg }
}
// gin上下文中的session key
func SessionWithGinCtxSessionKey(arg string) GinSessionOption {
return func(gsa *GinSessionAuth) { gsa.GinCtxSessionKey = arg }
}
// 获取token的key
func SessionWithTokenName(arg string) GinSessionOption {
return func(a *GinSessionAuth) { a.TokenName = arg }
}
// 可以获取到token的位置 引文,分割 header,query,cookie
func SessionWithTokenLookup(arg []string) GinSessionOption {
return func(a *GinSessionAuth) { a.TokenLookup = arg }
}
// 会话信息构造函数
func SessionWithSessionInfoConstructor(arg func(map[string]string) (user.ISessionInfo, error)) GinSessionOption {
return func(a *GinSessionAuth) { a.SessionInfoConstructor = arg }
}
func SessionWithCustomLoginHandler(arg IAuthLoginHandler) GinSessionOption {
return func(a *GinSessionAuth) { a.CustomLoginHandler = arg }
}
func NewGinSessionAuth(opts ...GinSessionOption) (IAuth, error) {
defaultSess := &GinSessionAuth{
PrefixKey: "session",
Expired: 3600 * 12,
GinCtxSessionKey: "session",
TokenName: "sessionid",
TokenLookup: []string{"header"},
SessionInfoConstructor: func(map[string]string) (user.ISessionInfo, error) { return &user.SessionInfo{}, nil },
}
for _, opt := range opts {
opt(defaultSess)
}
if defaultSess.CustomLoginHandler == nil {
return nil, fmt.Errorf("CustomLoginHandler is nil")
}
return defaultSess, nil
}
type GinSessionAuth struct {
Storage storage.AdapterCache // 缓存空间
PrefixKey string // 缓存key前缀
Expired int // 有效期(秒)
GinCtxSessionKey string // gin上下文中的session key
TokenName string // 获取token的key
TokenLookup []string // 可以获取到token的位置 引文,分割 header,query,cookie
SessionInfoConstructor func(map[string]string) (user.ISessionInfo, error) // 会话信息构造函数
CustomLoginHandler IAuthLoginHandler
}
func (g *GinSessionAuth) LoginHandler(ctx *gin.Context) {
// 生成token
sessionInfo, err := g.CustomLoginHandler(ctx)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &LoginResponse{
Code: http.StatusUnauthorized,
Msg: err.Error(),
})
return
}
endtime := time.Now().Add(time.Second * time.Duration(g.Expired))
token, err := g.UpdateSession(sessionInfo, endtime)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, &LoginResponse{
Code: http.StatusInternalServerError,
Msg: err.Error(),
})
return
}
/*
claim := sessionInfo.GetClaim()
claim["expire"] = endtime.Format(time.DateTime)
claim["timeStamp"] = cast.ToString(time.Now().Unix())
tokenid := utils.HmacObj(claim)
if tokenid == "" {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, &LoginResponse{
Code: http.StatusInternalServerError,
Msg: "token生成失败",
})
return
} else {
claim["sessionId"] = tokenid
}
sessionkey := g.PrefixKey + "_" + tokenid
if err := g.Storage.HashSet(sessionkey, claim, g.Expired); err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, &LoginResponse{
Code: http.StatusInternalServerError,
Msg: err.Error(),
})
return
}
*/
thirdInfo := make(map[string]interface{})
for k, v := range sessionInfo.GetThird() {
thirdInfo[k] = v
}
ctx.AbortWithStatusJSON(http.StatusOK, &LoginResponse{
Code: http.StatusOK,
Token: token,
Expire: int(endtime.Unix()),
Msg: "ok",
Third: thirdInfo,
})
}
func (g *GinSessionAuth) UpdateSession(info user.ISessionInfo, expiredAt time.Time) (string, error) {
claim := info.GetClaim()
claim["expire"] = expiredAt.Format(time.DateTime)
claim["timeStamp"] = cast.ToString(time.Now().Unix())
tokenid := utils.HmacObj(claim)
if tokenid == "" {
return "", fmt.Errorf("token生成失败")
} else {
claim["sessionId"] = tokenid
}
sessionkey := g.PrefixKey + "_" + tokenid
if err := g.Storage.HashSet(sessionkey, claim, g.Expired); err != nil {
return tokenid, fmt.Errorf("session更新失败: %w", err)
}
return tokenid, nil
}
func (g *GinSessionAuth) DeleteSession(ctx *gin.Context) error {
token, err := g.getToken(ctx)
if err != nil {
return err
}
sessionkey := g.PrefixKey + "_" + token
return g.Storage.Del(sessionkey)
}
// 获取token
func (g *GinSessionAuth) getToken(ctx *gin.Context) (string, error) {
for _, f := range g.TokenLookup {
switch f {
case "header":
token := ctx.Request.Header.Get(g.TokenName)
if token != "" {
return token, nil
}
case "query":
token := ctx.Query(g.TokenName)
if token != "" {
return token, nil
}
case "cookie":
cookie, err := ctx.Request.Cookie(g.TokenName)
if err != nil {
continue
} else if cookie.Value != "" {
return cookie.Value, nil
}
}
}
return "", fmt.Errorf("token not found from lookup [%s] with key [%s]", g.TokenLookup, g.TokenName)
}
func (g *GinSessionAuth) GetSessionInfo(ctx *gin.Context) (user.ISessionInfo, error) {
sessinf, exist := ctx.Get(g.GinCtxSessionKey)
if exist {
usess, ok := sessinf.(user.ISessionInfo)
if ok {
return usess, nil
}
}
token, err := g.getToken(ctx)
if err != nil {
return nil, err
}
sessionkey := g.PrefixKey + "_" + token
sessionInfo, err := g.Storage.HashGetAll(sessionkey)
if err != nil {
return nil, err
} else if len(sessionInfo) == 0 {
return nil, fmt.Errorf("session not found")
}
sessObj, err := g.SessionInfoConstructor(sessionInfo)
if err != nil {
return nil, err
}
return sessObj, nil
}
func (g *GinSessionAuth) MiddlewareFunc() gin.HandlerFunc {
return func(ctx *gin.Context) {
sessinf, err := g.GetSessionInfo(ctx)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &LoginResponse{
Code: http.StatusUnauthorized,
Msg: err.Error(),
})
return
}
ctx.Set(g.GinCtxSessionKey, sessinf)
ctx.Next()
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。