mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
auth: godoc: provider, claims provider, transformer, error handler and user helpers
This commit is contained in:
parent
c5139b22ee
commit
dceb09d4ff
13
auth/auth.go
13
auth/auth.go
|
@ -90,6 +90,19 @@ func New[T User](config Configuration) (*Auth[T], error) {
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithProviderAndErrorHandler registers a provider (if not nil) and
|
||||||
|
// an error handler (if not nil) and returns this "s" Auth instance.
|
||||||
|
// It's the same as calling AddProvider and SetErrorHandler at once.
|
||||||
|
// It's really useful when registering an Auth instance using the iris.Party.PartyConfigure
|
||||||
|
// method when a Provider of T and ErrorHandler is available through the registered Party's dependencies.
|
||||||
|
//
|
||||||
|
// Usage Example:
|
||||||
|
// api := app.Party("/api")
|
||||||
|
// api.EnsureStaticBindings().RegisterDependency(
|
||||||
|
// NewAuthProviderErrorHandler(),
|
||||||
|
// NewAuthCustomerProvider,
|
||||||
|
// auth.Must(auth.New[Customer](authConfig)).WithProviderAndErrorHandler,
|
||||||
|
// )
|
||||||
func (s *Auth[T]) WithProviderAndErrorHandler(provider Provider[T], errHandler ErrorHandler) *Auth[T] {
|
func (s *Auth[T]) WithProviderAndErrorHandler(provider Provider[T], errHandler ErrorHandler) *Auth[T] {
|
||||||
if provider != nil {
|
if provider != nil {
|
||||||
for i := range s.providers {
|
for i := range s.providers {
|
||||||
|
|
|
@ -18,13 +18,15 @@ type VerifiedToken = jwt.VerifiedToken
|
||||||
// by a custom value type to provide user information to the Auth's
|
// by a custom value type to provide user information to the Auth's
|
||||||
// JWT Token Signer and Verifier.
|
// JWT Token Signer and Verifier.
|
||||||
//
|
//
|
||||||
// A provider can implement Transformer and ErrorHandler and ClaimsProvider as well.
|
// A provider can optionally complete the Transformer, ClaimsProvider and
|
||||||
|
// ErrorHandler all in once when necessary.
|
||||||
|
// Set a provider using the AddProvider method of Auth type.
|
||||||
type Provider[T User] interface {
|
type Provider[T User] interface {
|
||||||
// Signin accepts a username (or email) and a password and should
|
// Signin accepts a username (or email) and a password and should
|
||||||
// return a valid T value or an error describing
|
// return a valid T value or an error describing
|
||||||
// the user authentication or verification reason of failure.
|
// the user authentication or verification reason of failure.
|
||||||
//
|
//
|
||||||
// It's called on auth.SigninHandler
|
// It's called on Auth.SigninHandler
|
||||||
Signin(ctx stdContext.Context, username, password string) (T, error)
|
Signin(ctx stdContext.Context, username, password string) (T, error)
|
||||||
|
|
||||||
// ValidateToken accepts the standard JWT claims and the T value obtained
|
// ValidateToken accepts the standard JWT claims and the T value obtained
|
||||||
|
@ -34,7 +36,7 @@ type Provider[T User] interface {
|
||||||
// the standard claim's (e.g. origin jwt token id).
|
// the standard claim's (e.g. origin jwt token id).
|
||||||
// It can be an empty method too which returns a nil error.
|
// It can be an empty method too which returns a nil error.
|
||||||
//
|
//
|
||||||
// It's caleld on auth.VerifyHandler.
|
// It's caleld on Auth.VerifyHandler.
|
||||||
ValidateToken(ctx stdContext.Context, standardClaims StandardClaims, t T) error
|
ValidateToken(ctx stdContext.Context, standardClaims StandardClaims, t T) error
|
||||||
|
|
||||||
// InvalidateToken is optional and can be used to allow tokens to be invalidated
|
// InvalidateToken is optional and can be used to allow tokens to be invalidated
|
||||||
|
@ -42,13 +44,13 @@ type Provider[T User] interface {
|
||||||
// on a persistence storage and server can decide which token is valid or invalid.
|
// on a persistence storage and server can decide which token is valid or invalid.
|
||||||
// It can be an empty method too which returns a nil error.
|
// It can be an empty method too which returns a nil error.
|
||||||
//
|
//
|
||||||
// It's called on auth.SignoutHandler.
|
// It's called on Auth.SignoutHandler.
|
||||||
InvalidateToken(ctx stdContext.Context, standardClaims StandardClaims, t T) error
|
InvalidateToken(ctx stdContext.Context, standardClaims StandardClaims, t T) error
|
||||||
// InvalidateTokens is like InvalidateToken but it should invalidate
|
// InvalidateTokens is like InvalidateToken but it should invalidate
|
||||||
// all tokens generated for a specific T value.
|
// all tokens generated for a specific T value.
|
||||||
// It can be an empty method too which returns a nil error.
|
// It can be an empty method too which returns a nil error.
|
||||||
//
|
//
|
||||||
// It's called on auth.SignoutAllHandler.
|
// It's called on Auth.SignoutAllHandler.
|
||||||
InvalidateTokens(ctx stdContext.Context, t T) error
|
InvalidateTokens(ctx stdContext.Context, t T) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,27 +62,51 @@ type ClaimsProvider interface {
|
||||||
GetRefreshTokenClaims(accessClaims StandardClaims) StandardClaims
|
GetRefreshTokenClaims(accessClaims StandardClaims) StandardClaims
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transformer is an optional interface which can be implemented by a Provider as well.
|
||||||
|
// Set a Transformer through Auth.SetTransformer or Auth.SetTransformerFunc or by implementing
|
||||||
|
// the Transform method inside a Provider which can be registered through the Auth.AddProvider
|
||||||
|
// method.
|
||||||
|
//
|
||||||
|
// A transformer is called on Auth.VerifyHandler before Provider.ValidateToken and it can
|
||||||
|
// be used to modify the T value based on the token's contents. It is mostly used
|
||||||
|
// to convert the json claims to T value manually, when they differ.
|
||||||
type Transformer[T User] interface {
|
type Transformer[T User] interface {
|
||||||
Transform(ctx stdContext.Context, tok *VerifiedToken) (T, error)
|
Transform(ctx stdContext.Context, tok *VerifiedToken) (T, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TransformerFunc completes the Transformer interface.
|
||||||
type TransformerFunc[T User] func(ctx stdContext.Context, tok *VerifiedToken) (T, error)
|
type TransformerFunc[T User] func(ctx stdContext.Context, tok *VerifiedToken) (T, error)
|
||||||
|
|
||||||
|
// Transform calls itself.
|
||||||
func (fn TransformerFunc[T]) Transform(ctx stdContext.Context, tok *VerifiedToken) (T, error) {
|
func (fn TransformerFunc[T]) Transform(ctx stdContext.Context, tok *VerifiedToken) (T, error) {
|
||||||
return fn(ctx, tok)
|
return fn(ctx, tok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrorHandler is an optional interface which can be implemented by a Provider as well.
|
||||||
|
//
|
||||||
|
// ErrorHandler is the interface which controls the HTTP errors on
|
||||||
|
// Auth.SigninHandler, Auth.VerifyHandler, Auth.SignoutHandler and
|
||||||
|
// Auth.SignoutAllHandler handelrs.
|
||||||
type ErrorHandler interface {
|
type ErrorHandler interface {
|
||||||
|
// InvalidArgument should handle any 400 (bad request) errors,
|
||||||
|
// e.g. invalid request body.
|
||||||
InvalidArgument(ctx *context.Context, err error)
|
InvalidArgument(ctx *context.Context, err error)
|
||||||
|
// Unauthenticated should handle any 401 (unauthenticated) errors,
|
||||||
|
// e.g. user not found or invalid credentials.
|
||||||
Unauthenticated(ctx *context.Context, err error)
|
Unauthenticated(ctx *context.Context, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultErrorHandler is the default registered ErrorHandler which can be
|
||||||
|
// replaced through the Auth.SetErrorHandler method.
|
||||||
type DefaultErrorHandler struct{}
|
type DefaultErrorHandler struct{}
|
||||||
|
|
||||||
|
// InvalidArgument sends 400 (bad request) with "unable to parse body" as its message
|
||||||
|
// and the "err" value as its details.
|
||||||
func (e *DefaultErrorHandler) InvalidArgument(ctx *context.Context, err error) {
|
func (e *DefaultErrorHandler) InvalidArgument(ctx *context.Context, err error) {
|
||||||
errors.InvalidArgument.Details(ctx, "unable to parse body", err.Error())
|
errors.InvalidArgument.Details(ctx, "unable to parse body", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unauthenticated sends 401 (unauthenticated) with the "err" value as its message.
|
||||||
func (e *DefaultErrorHandler) Unauthenticated(ctx *context.Context, err error) {
|
func (e *DefaultErrorHandler) Unauthenticated(ctx *context.Context, err error) {
|
||||||
errors.Unauthenticated.Err(ctx, err)
|
errors.Unauthenticated.Err(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
17
auth/user.go
17
auth/user.go
|
@ -9,18 +9,25 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// StandardClaims is an alias of jwt.Claims, it holds the standard JWT claims.
|
||||||
StandardClaims = jwt.Claims
|
StandardClaims = jwt.Claims
|
||||||
User = interface{} // any type.
|
// User is an alias of an empty interface, it's here to declare the typeof T,
|
||||||
|
// which can be any custom struct type.
|
||||||
|
User = interface{}
|
||||||
)
|
)
|
||||||
|
|
||||||
const accessTokenContextKey = "iris.auth.context.access_token"
|
const accessTokenContextKey = "iris.auth.context.access_token"
|
||||||
|
|
||||||
|
// GetAccessToken accepts the iris Context and returns the raw access token value.
|
||||||
|
// It's only available after Auth.VerifyHandler is executed.
|
||||||
func GetAccessToken(ctx *context.Context) string {
|
func GetAccessToken(ctx *context.Context) string {
|
||||||
return ctx.Values().GetString(accessTokenContextKey)
|
return ctx.Values().GetString(accessTokenContextKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
const standardClaimsContextKey = "iris.auth.context.standard_claims"
|
const standardClaimsContextKey = "iris.auth.context.standard_claims"
|
||||||
|
|
||||||
|
// GetStandardClaims accepts the iris Context and returns the standard token's claims.
|
||||||
|
// It's only available after Auth.VerifyHandler is executed.
|
||||||
func GetStandardClaims(ctx *context.Context) StandardClaims {
|
func GetStandardClaims(ctx *context.Context) StandardClaims {
|
||||||
if v := ctx.Values().Get(standardClaimsContextKey); v != nil {
|
if v := ctx.Values().Get(standardClaimsContextKey); v != nil {
|
||||||
if c, ok := v.(StandardClaims); ok {
|
if c, ok := v.(StandardClaims); ok {
|
||||||
|
@ -31,12 +38,10 @@ func GetStandardClaims(ctx *context.Context) StandardClaims {
|
||||||
return StandardClaims{}
|
return StandardClaims{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Auth[T]) GetStandardClaims(ctx *context.Context) StandardClaims {
|
|
||||||
return GetStandardClaims(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
const userContextKey = "iris.auth.context.user"
|
const userContextKey = "iris.auth.context.user"
|
||||||
|
|
||||||
|
// GetUser is the package-level function of the Auth.GetUser method.
|
||||||
|
// It returns the T user value after Auth.VerifyHandler is executed.
|
||||||
func GetUser[T User](ctx *context.Context) T {
|
func GetUser[T User](ctx *context.Context) T {
|
||||||
if v := ctx.Values().Get(userContextKey); v != nil {
|
if v := ctx.Values().Get(userContextKey); v != nil {
|
||||||
if t, ok := v.(T); ok {
|
if t, ok := v.(T); ok {
|
||||||
|
@ -48,6 +53,8 @@ func GetUser[T User](ctx *context.Context) T {
|
||||||
return empty
|
return empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUser accepts the iris Context and returns the T custom user/claims struct value.
|
||||||
|
// It's only available after Auth.VerifyHandler is executed.
|
||||||
func (s *Auth[T]) GetUser(ctx *context.Context) T {
|
func (s *Auth[T]) GetUser(ctx *context.Context) T {
|
||||||
return GetUser[T](ctx)
|
return GetUser[T](ctx)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user