1 Star 0 Fork 0

linxing/youye-core

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
sessionauth.go 6.44 KB
一键复制 编辑 原始数据 按行查看 历史
Mark 提交于 2024-04-27 21:23 . feat: auth添加注入session信息函数
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()
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/linxing_3/youye-core.git
git@gitee.com:linxing_3/youye-core.git
linxing_3
youye-core
youye-core
v0.0.1-202406121011

搜索帮助