80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
package authtoken
|
|
|
|
import (
|
|
"RenewCMS/api/pkg/apperr"
|
|
"context"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
CookieName = "jwt"
|
|
bearerPrefix = "bearer "
|
|
)
|
|
|
|
type contextKey struct{}
|
|
|
|
type verdict struct {
|
|
claims Claims
|
|
err error
|
|
}
|
|
|
|
func Verifier(auth *Auth) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
claims, err := auth.Decode(tokenFromRequest(r))
|
|
next.ServeHTTP(w, r.WithContext(NewContext(r.Context(), claims, err)))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Authenticator(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if _, err := FromContext(r.Context()); err != nil {
|
|
http.Error(w, apperr.UnauthorizedErrorMessage, http.StatusUnauthorized)
|
|
return
|
|
}
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
func NewContext(ctx context.Context, claims Claims, err error) context.Context {
|
|
return context.WithValue(ctx, contextKey{}, verdict{claims: claims, err: err})
|
|
}
|
|
|
|
func FromContext(ctx context.Context) (Claims, error) {
|
|
stored, ok := ctx.Value(contextKey{}).(verdict)
|
|
switch {
|
|
case !ok:
|
|
return nil, ErrNoToken
|
|
case stored.err != nil:
|
|
return nil, stored.err
|
|
case stored.claims == nil:
|
|
return nil, ErrNoToken
|
|
}
|
|
return stored.claims, nil
|
|
}
|
|
|
|
func tokenFromRequest(r *http.Request) string {
|
|
if token := tokenFromHeader(r); token != "" {
|
|
return token
|
|
}
|
|
return tokenFromCookie(r)
|
|
}
|
|
|
|
func tokenFromHeader(r *http.Request) string {
|
|
header := r.Header.Get("Authorization")
|
|
if len(header) <= len(bearerPrefix) || !strings.EqualFold(header[:len(bearerPrefix)], bearerPrefix) {
|
|
return ""
|
|
}
|
|
return header[len(bearerPrefix):]
|
|
}
|
|
|
|
func tokenFromCookie(r *http.Request) string {
|
|
cookie, err := r.Cookie(CookieName)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return cookie.Value
|
|
}
|