50 lines
1.2 KiB
Go
50 lines
1.2 KiB
Go
package authcommon
|
|
|
|
import (
|
|
"context"
|
|
"crypto/subtle"
|
|
"encoding/base64"
|
|
"strings"
|
|
|
|
"cmroubao/backend-api/internal/domain"
|
|
)
|
|
|
|
const (
|
|
AdminSessionCookieName = "cmroubao_admin_session"
|
|
CSRFCookieName = "cmroubao_admin_csrf"
|
|
CSRFFormField = "csrf_token"
|
|
CSRFHeader = "X-CSRF-Token"
|
|
)
|
|
|
|
type principalContextKey struct{}
|
|
|
|
func WithPrincipal(
|
|
ctx context.Context,
|
|
principal domain.AuthPrincipal,
|
|
) context.Context {
|
|
return context.WithValue(ctx, principalContextKey{}, principal)
|
|
}
|
|
|
|
func Principal(ctx context.Context) (domain.AuthPrincipal, bool) {
|
|
principal, ok := ctx.Value(principalContextKey{}).(domain.AuthPrincipal)
|
|
return principal, ok
|
|
}
|
|
|
|
func ValidCSRFPair(cookieValue, presentedValue string) bool {
|
|
cookieValue = strings.TrimSpace(cookieValue)
|
|
presentedValue = strings.TrimSpace(presentedValue)
|
|
if !ValidOpaqueValue(cookieValue) ||
|
|
len(cookieValue) != len(presentedValue) {
|
|
return false
|
|
}
|
|
return subtle.ConstantTimeCompare(
|
|
[]byte(cookieValue),
|
|
[]byte(presentedValue),
|
|
) == 1
|
|
}
|
|
|
|
func ValidOpaqueValue(value string) bool {
|
|
decoded, err := base64.RawURLEncoding.DecodeString(value)
|
|
return err == nil && len(decoded) == 32
|
|
}
|