JWT Authentication
Jump to Section
In case you decide to use JWT as your Auth* of choice, Mortar have a simple Token Extractor.
type TokenExtractor interface {
// FromContext should try to extract a token from the Context using `ContextExtractor`
FromContext(ctx context.Context) (Token, error)
// FromString accepts a JWT token in form of a string
// xxxxx.yyyyy.zzzzz
FromString(str string) (Token, error)
}
Mortar and gRPC-Gateway
Usually you pass the JWT Token via the Authorization
header
Authorization: bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Now, you are encouraged to use gRPC-Gateway, but in this case you don’t really have an access to HTTP Request Headers. Fear not, gRPC-Gateway and Mortar have your covered.
- By default gRPC-Gateway will transform this special
Authorization
header intogrpcgateway-authorization
and put it in the Context. - Mortar have a
DefaultJWTTokenExtractor
that takes care of that.
Example
You only need to register Token Extractor by providing DefaultJWTTokenExtractor
constructor to Uber-Fx.
import (
"github.com/go-masonry/mortar/constructors"
"go.uber.org/fx"
)
...
fx.Provide(constructors.DefaultJWTTokenExtractor)
...
Once provided, you can inject TokenExtractor
and use it
type authDeps struct {
fx.In
TokenExtractor jwt.TokenExtractor
}
...
func (impl *authImpl) CheckJWT(ctx context.Context) error {
// we only log for error here
token, err := impl.deps.TokenExtractor.FromContext(ctx)
if err != nil {
return fmt.Errorf("no jwt token found, %w",err)
}
m, err = token.Map()
if err != nil {
return fmt.Errorf("failed to produce a map from authorization header, %w", err)
}
...
...
return nil
}
Mortar service template have a simple working example. Look at app/validations/auth.go.