README
¶
JWT interceptor
In this example, we will try to create unary grpc server with JWT interceptor enabled.
Please make sure panic interceptor to be added at last in chain of interceptors.
Table of Contents generated with DocToc
Quick start
Get rk-grpc package from the remote repository.
go get -u github.com/rookie-ninja/rk-grpc
Code
import "github.com/rookie-ninja/rk-grpc/interceptor/jwt"
// *************************************
// ********** Unary Server *************
// *************************************
opts := []grpc.ServerOption{
grpc.ChainUnaryInterceptor(
rkgrpcjwt.UnaryServerInterceptor(
// Required, entry name and entry type will be used for distinguishing interceptors. Recommended.
//rkgrpcjwt.WithEntryNameAndType("greeter", "grpc"),
//
// Required, provide signing key.
rkgrpcjwt.WithSigningKey([]byte("my-secret")),
//
// Optional, provide skipper function
//rkgrpcjwt.WithSkipper(func(fullMethod string) bool {
// return true
//}),
//
// Optional, provide token parse function, default one will be assigned.
//rkgrpcjwt.WithParseTokenFunc(func(auth string, ctx context.Context) (*jwt.Token, error) {
// return nil, nil
//}),
//
// Optional, provide key function, default one will be assigned.
//rkgrpcjwt.WithKeyFunc(func(token *jwt.Token) (interface{}, error) {
// return nil, nil
//}),
//
// Optional, default is Bearer
//rkgrpcjwt.WithAuthScheme("Bearer"),
//
// Optional
//rkechojwt.WithTokenLookup("header:my-jwt-header-key"),
//
// Optional, default is HS256
//rkgrpcjwt.WithSigningAlgorithm(rkgrpcjwt.AlgorithmHS256),
),
),
}
// *************************************
// ********** Stream Server ************
// *************************************
opts := []grpc.ServerOption {
grpc.ChainStreamInterceptor(
rkgrpcjwt.StreamServerInterceptor(
rkgrpcjwt.WithSigningKey([]byte("my-secret")),
),
),
}
Options
Name | Description | Default Values |
---|---|---|
rkgrpcjwt.WithEntryNameAndType(entryName, entryType string) | Optional. Provide entry name and type if there are multiple jwt interceptors needs to be used. | grpc, grpc |
rkgrpcjwt.WithSkipper(skipper function) | Optional. Provide skipper function | function always returns false |
rkgrpcjwt.WithSigningKey(interface{}) | Required. Provide signing key | nil |
rkgrpcjwt.WithSigningKeys(string, interface{}) | Optional. Provide signing key value pairs | empty |
rkgrpcjwt.WithSigningAlgorithm(string) | Optional, Provide signing algorithm. | HS256 |
rkgrpcjwt.WithClaims(jwt.Claims) | Optional, provide jwt.Claims. | jwt.MapClaims{} |
rkgrpcjwt.WithTokenLookup(string) | Optional, provide jwt token lookup rules, please see code comments for details. | "header:Authorization" |
rkgrpcjwt.WithAuthScheme(string) | Optional, provide auth scheme. | Bearer |
rkgrpcjwt.WithKeyFunc(jwt.Keyfunc) | Optional, provide key function. | default function will be assigned. |
rkgrpcjwt.WithParseTokenFunc(func) | Optional, provide token parse function. | default function will be assigned. |
rkgrpcjwt.WithIgnorePrefix([]string) | Optional, provide ignoring path prefix. | [] |
// ********************************************
// ********** Enable interceptors *************
// ********************************************
opts := []grpc.ServerOption{
grpc.ChainUnaryInterceptor(
rkgrpcjwt.UnaryServerInterceptor(
rkgrpcjwt.WithSigningKey([]byte("my-secret")),
),
),
}
Context Usage
Name | Functionality |
---|---|
rkgrpcctx.GetLogger(context.Context) | Get logger generated by log interceptor. If there are X-Request-Id or X-Trace-Id as headers in incoming and outgoing metadata, then loggers will has requestId and traceId attached by default. |
rkgrpcctx.GetEvent(context.Context) | Get event generated by log interceptor. Event would be printed as soon as RPC finished. ClientStream is a little bit tricky. Please refer rkgrpcctx.FinishClientStream() function for details. |
rkgrpcctx.GetIncomingHeaders(context.Context) | Get incoming header. ClientStream is a little bit tricky, please use stream.Header() instead. |
rkgrpcctx.AddHeaderToClient(ctx, "k", "v") | Add k/v to headers which would be sent to client. |
rkgrpcctx.AddHeaderToServer(ctx, "k", "v") | Add k/v to headers which would be sent to server. |
rkgrpcctx.GetJwtToken(ctx) | Get jwt token if exists |
Example
Unary
Create a simple unary server and client with bellow protocol buffer files. We will enable log interceptor at the same time.
Start server
$ go run greeter-server.go
Send request
- with valid jwt token
$ grpcurl -plaintext -H "Authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.EpM5XBzTJZ4J8AfoJEcJrjth8pfH28LWdjLo90sYb9g" localhost:8080 Greeter.SayHello
{
"message": "Is token valid:true!"
}
- with invalid jwt token
$ grpcurl -plaintext -H "Authorization:Bearer invalid-jwt-token" localhost:8080 Greeter.SayHello
ERROR:
Code: Unauthenticated
Message: invalid or expired jwt
Details:
1) {"@type":"type.googleapis.com/rk.api.v1.ErrorDetail","code":16,"message":"[from-grpc] invalid or expired jwt","status":"Unauthenticated"}
2) {"@type":"type.googleapis.com/rk.api.v1.ErrorDetail","code":2,"message":"token contains an invalid number of segments","status":"Unknown"}
Code
Click to show internal directories.
Click to hide internal directories.