推进活动系统最小成品闭环与游客体验

This commit is contained in:
2026-04-07 19:05:18 +08:00
parent 1a6008449e
commit 6cd16f08dd
102 changed files with 16087 additions and 3556 deletions

View File

@@ -17,6 +17,7 @@ const authKey authContextKey = "auth"
type AuthContext struct {
UserID string
UserPublicID string
RoleCode string
}
func NewAuthMiddleware(jwtManager *jwtx.Manager) func(http.Handler) http.Handler {
@@ -34,10 +35,15 @@ func NewAuthMiddleware(jwtManager *jwtx.Manager) func(http.Handler) http.Handler
httpx.WriteError(w, apperr.New(http.StatusUnauthorized, "invalid_token", "invalid access token"))
return
}
if claims.ActorType != "" && claims.ActorType != "user" {
httpx.WriteError(w, apperr.New(http.StatusUnauthorized, "invalid_token", "invalid access token"))
return
}
ctx := context.WithValue(r.Context(), authKey, &AuthContext{
UserID: claims.UserID,
UserPublicID: claims.UserPublicID,
RoleCode: claims.RoleCode,
})
next.ServeHTTP(w, r.WithContext(ctx))
})

View File

@@ -0,0 +1,77 @@
package middleware
import (
"context"
"net/http"
"strings"
"cmr-backend/internal/apperr"
"cmr-backend/internal/httpx"
"cmr-backend/internal/platform/jwtx"
)
type opsAuthContextKey string
const opsAuthKey opsAuthContextKey = "ops-auth"
type OpsAuthContext struct {
OpsUserID string
OpsUserPublicID string
RoleCode string
}
func NewOpsAuthMiddleware(jwtManager *jwtx.Manager, appEnv string) func(http.Handler) http.Handler {
devContext := func(r *http.Request) *http.Request {
ctx := context.WithValue(r.Context(), opsAuthKey, &OpsAuthContext{
OpsUserID: "dev-ops-user",
OpsUserPublicID: "ops_dev_console",
RoleCode: "owner",
})
return r.WithContext(ctx)
}
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authHeader := strings.TrimSpace(r.Header.Get("Authorization"))
if authHeader == "" || !strings.HasPrefix(authHeader, "Bearer ") {
if appEnv != "production" {
next.ServeHTTP(w, devContext(r))
return
}
httpx.WriteError(w, apperr.New(http.StatusUnauthorized, "unauthorized", "missing bearer token"))
return
}
token := strings.TrimSpace(strings.TrimPrefix(authHeader, "Bearer "))
claims, err := jwtManager.ParseAccessToken(token)
if err != nil {
if appEnv != "production" {
next.ServeHTTP(w, devContext(r))
return
}
httpx.WriteError(w, apperr.New(http.StatusUnauthorized, "invalid_token", "invalid access token"))
return
}
if claims.ActorType != "ops" {
if appEnv != "production" {
next.ServeHTTP(w, devContext(r))
return
}
httpx.WriteError(w, apperr.New(http.StatusUnauthorized, "invalid_token", "invalid ops access token"))
return
}
ctx := context.WithValue(r.Context(), opsAuthKey, &OpsAuthContext{
OpsUserID: claims.UserID,
OpsUserPublicID: claims.UserPublicID,
RoleCode: claims.RoleCode,
})
next.ServeHTTP(w, r.WithContext(ctx))
})
}
}
func GetOpsAuthContext(ctx context.Context) *OpsAuthContext {
auth, _ := ctx.Value(opsAuthKey).(*OpsAuthContext)
return auth
}