48 lines
1.3 KiB
Go
48 lines
1.3 KiB
Go
|
|
package middleware
|
||
|
|
|
||
|
|
import (
|
||
|
|
"net/http"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
errs "gateway/internal/library/errors"
|
||
|
|
"gateway/internal/library/errors/code"
|
||
|
|
logicmember "gateway/internal/logic/member"
|
||
|
|
domauth "gateway/internal/model/auth/domain/usecase"
|
||
|
|
"gateway/internal/response"
|
||
|
|
|
||
|
|
"github.com/zeromicro/go-zero/rest"
|
||
|
|
)
|
||
|
|
|
||
|
|
// CloudEPJWT parses Bearer access tokens and injects member actor into request context.
|
||
|
|
// When token is absent or invalid, the request proceeds unchanged (dev headers may still apply on member routes).
|
||
|
|
func CloudEPJWT(tokens domauth.TokenUseCase) rest.Middleware {
|
||
|
|
return func(next http.HandlerFunc) http.HandlerFunc {
|
||
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
ctx := r.Context()
|
||
|
|
raw := bearerToken(r.Header.Get("Authorization"))
|
||
|
|
if raw != "" && tokens != nil {
|
||
|
|
claims, err := tokens.ParseAccessToken(ctx, raw)
|
||
|
|
if err == nil {
|
||
|
|
ctx = logicmember.WithActor(ctx, claims.TenantID, claims.UID)
|
||
|
|
r = r.WithContext(ctx)
|
||
|
|
next(w, r)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if e := errs.FromError(err); e != nil && e.Category() == code.AuthUnauthorized {
|
||
|
|
response.Write(r.Context(), w, nil, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
}
|
||
|
|
next(w, r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func bearerToken(header string) string {
|
||
|
|
const prefix = "Bearer "
|
||
|
|
if !strings.HasPrefix(header, prefix) {
|
||
|
|
return ""
|
||
|
|
}
|
||
|
|
return strings.TrimSpace(strings.TrimPrefix(header, prefix))
|
||
|
|
}
|