Files
neo-blog/internal/middleware/auth.go
Snowykami e659de23fb ️ feat: refactor sorting parameters in post listing API and components
- 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.
2025-07-26 09:48:23 +08:00

83 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}