mirror of
https://github.com/snowykami/neo-blog.git
synced 2025-09-03 15:56:22 +00:00
- Renamed `orderedBy` to `orderBy` and `reverse` to `desc` in ListPostsParams interface and related functions. - Updated all usages of the sorting parameters in the post listing logic to reflect the new naming convention. feat: add user-related API functions - Implemented `getLoginUser` and `getUserById` functions in the user API to fetch user details. - Enhanced user model to include `language` property. feat: integrate next-intl for internationalization - Added `next-intl` plugin to Next.js configuration for improved localization support. - Removed previous i18n implementation and replaced it with a new structure using JSON files for translations. - Created locale files for English, Japanese, and Chinese with basic translations. - Implemented a request configuration to handle user locales and messages dynamically. fix: clean up unused imports and code - Removed unused i18n utility functions and language settings from device context. - Cleaned up commented-out code in blog card component and sidebar. chore: update dependencies - Added `deepmerge` for merging locale messages. - Updated package.json and pnpm-lock.yaml to reflect new dependencies.
83 lines
2.6 KiB
Go
83 lines
2.6 KiB
Go
package middleware
|
||
|
||
import (
|
||
"context"
|
||
"github.com/cloudwego/hertz/pkg/app"
|
||
"github.com/snowykami/neo-blog/internal/ctxutils"
|
||
"github.com/snowykami/neo-blog/internal/repo"
|
||
"github.com/snowykami/neo-blog/pkg/constant"
|
||
"github.com/snowykami/neo-blog/pkg/resps"
|
||
"github.com/snowykami/neo-blog/pkg/utils"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
func UseAuth(block bool) app.HandlerFunc {
|
||
return func(ctx context.Context, c *app.RequestContext) {
|
||
// For cookie
|
||
tokenFromCookie := string(c.Cookie("tokenFromCookie"))
|
||
tokenFromHeader := strings.TrimPrefix(string(c.GetHeader("Authorization")), "Bearer ")
|
||
refreshToken := string(c.Cookie("refresh_token"))
|
||
|
||
// 尝试用普通 tokenFromCookie 认证
|
||
if tokenFromCookie != "" {
|
||
tokenClaims, err := utils.Jwt.ParseJsonWebTokenWithoutState(tokenFromCookie)
|
||
if err == nil && tokenClaims != nil {
|
||
ctx = context.WithValue(ctx, constant.ContextKeyUserID, tokenClaims.UserID)
|
||
c.Next(ctx)
|
||
return
|
||
}
|
||
}
|
||
// tokenFromCookie 认证失败,尝试用 Bearer tokenFromHeader 认证
|
||
if tokenFromHeader != "" {
|
||
tokenClaims, err := utils.Jwt.ParseJsonWebTokenWithoutState(tokenFromHeader)
|
||
if err == nil && tokenClaims != nil {
|
||
ctx = context.WithValue(ctx, constant.ContextKeyUserID, tokenClaims.UserID)
|
||
c.Next(ctx)
|
||
return
|
||
}
|
||
}
|
||
// tokenFromCookie 失效 使用 refresh tokenFromCookie 重新签发和鉴权
|
||
refreshTokenClaims, err := utils.Jwt.ParseJsonWebTokenWithoutState(refreshToken)
|
||
if err == nil && refreshTokenClaims != nil {
|
||
ok, err := isStatefulJwtValid(refreshTokenClaims)
|
||
if err == nil && ok {
|
||
ctx = context.WithValue(ctx, constant.ContextKeyUserID, refreshTokenClaims.UserID)
|
||
// 生成新 tokenFromCookie
|
||
newTokenClaims := utils.Jwt.NewClaims(
|
||
refreshTokenClaims.UserID,
|
||
refreshTokenClaims.SessionKey,
|
||
refreshTokenClaims.Stateful,
|
||
time.Duration(utils.Env.GetAsInt(constant.EnvKeyRefreshTokenDuration, 30)*int(time.Hour)),
|
||
)
|
||
newToken, err := newTokenClaims.ToString()
|
||
if err == nil {
|
||
ctxutils.SetTokenCookie(c, newToken)
|
||
} else {
|
||
resps.InternalServerError(c, resps.ErrInternalServerError)
|
||
}
|
||
|
||
c.Next(ctx)
|
||
return
|
||
}
|
||
}
|
||
|
||
// 所有认证方式都失败
|
||
if block {
|
||
// 若需要阻断,返回未授权错误并中止请求
|
||
resps.Unauthorized(c, resps.ErrUnauthorized)
|
||
c.Abort()
|
||
} else {
|
||
// 若不需要阻断,继续请求但不设置用户ID
|
||
c.Next(ctx)
|
||
}
|
||
}
|
||
}
|
||
|
||
func isStatefulJwtValid(claims *utils.Claims) (bool, error) {
|
||
if !claims.Stateful {
|
||
return true, nil
|
||
}
|
||
return repo.Session.IsSessionValid(claims.SessionKey)
|
||
}
|