mirror of
https://github.com/zhufuyi/sponge.git
synced 2025-11-01 21:12:54 +08:00
rpc jwt token
This commit is contained in:
@@ -160,7 +160,8 @@ service userExampleService {
|
|||||||
// to ensure that the front end and back end JSON naming is consistent.
|
// to ensure that the front end and back end JSON naming is consistent.
|
||||||
// (3) If the declared route path includes a variable, such as /api/v1/userExample/{id},
|
// (3) If the declared route path includes a variable, such as /api/v1/userExample/{id},
|
||||||
// the request parameter of the rpc method contains the route variable field and this field
|
// the request parameter of the rpc method contains the route variable field and this field
|
||||||
// must be annotated, such as int64 id = 1 [(tagger.tags) = "uri:\"id\"" ]
|
// must be annotated, such as int64 id = 1 [(tagger.tags) = "uri:\"id\""]; If the get method is used,
|
||||||
|
// the request parameters must be annotated with form, e.g. uint productID = 1 [(tagger.tags) = "form:\"productID\""].
|
||||||
|
|
||||||
|
|
||||||
enum GenderType {
|
enum GenderType {
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
"github.com/zhufuyi/sponge/docs"
|
"github.com/zhufuyi/sponge/docs"
|
||||||
"github.com/zhufuyi/sponge/internal/config"
|
"github.com/zhufuyi/sponge/internal/config"
|
||||||
"github.com/zhufuyi/sponge/internal/ecode"
|
|
||||||
|
|
||||||
|
"github.com/zhufuyi/sponge/pkg/errcode"
|
||||||
"github.com/zhufuyi/sponge/pkg/gin/handlerfunc"
|
"github.com/zhufuyi/sponge/pkg/gin/handlerfunc"
|
||||||
"github.com/zhufuyi/sponge/pkg/gin/middleware"
|
"github.com/zhufuyi/sponge/pkg/gin/middleware"
|
||||||
"github.com/zhufuyi/sponge/pkg/gin/middleware/metrics"
|
"github.com/zhufuyi/sponge/pkg/gin/middleware/metrics"
|
||||||
@@ -71,8 +71,8 @@ func NewRouter_pbExample() *gin.Engine { //nolint
|
|||||||
if config.Get().App.EnableCircuitBreaker {
|
if config.Get().App.EnableCircuitBreaker {
|
||||||
r.Use(middleware.CircuitBreaker(
|
r.Use(middleware.CircuitBreaker(
|
||||||
// set http code for circuit breaker, default already includes 500 and 503
|
// set http code for circuit breaker, default already includes 500 and 503
|
||||||
middleware.WithValidCode(ecode.InternalServerError.Code()),
|
middleware.WithValidCode(errcode.InternalServerError.Code()),
|
||||||
middleware.WithValidCode(ecode.ServiceUnavailable.Code()),
|
middleware.WithValidCode(errcode.ServiceUnavailable.Code()),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -166,6 +166,12 @@ func (s *grpcServer) unaryServerOptions() grpc.ServerOption {
|
|||||||
unaryServerInterceptors = append(unaryServerInterceptors, interceptor.UnaryServerToken(checkToken))
|
unaryServerInterceptors = append(unaryServerInterceptors, interceptor.UnaryServerToken(checkToken))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jwt token interceptor
|
||||||
|
//unaryServerInterceptors = append(unaryServerInterceptors, interceptor.UnaryServerJwtAuth(
|
||||||
|
// // set ignore rpc methods(full path) for jwt token
|
||||||
|
// interceptor.WithAuthIgnoreMethods("/api.user.v1.User/Register", "/api.user.v1.User/Login"),
|
||||||
|
//))
|
||||||
|
|
||||||
// metrics interceptor
|
// metrics interceptor
|
||||||
if config.Get().App.EnableMetrics {
|
if config.Get().App.EnableMetrics {
|
||||||
unaryServerInterceptors = append(unaryServerInterceptors, interceptor.UnaryServerMetrics())
|
unaryServerInterceptors = append(unaryServerInterceptors, interceptor.UnaryServerMetrics())
|
||||||
@@ -206,6 +212,24 @@ func (s *grpcServer) streamServerOptions() grpc.ServerOption {
|
|||||||
logger.Get(),
|
logger.Get(),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
// token interceptor
|
||||||
|
if config.Get().Grpc.EnableToken {
|
||||||
|
checkToken := func(appID string, appKey string) error {
|
||||||
|
// todo the defaultTokenAppID and defaultTokenAppKey are usually retrieved from the cache or database
|
||||||
|
if appID != defaultTokenAppID || appKey != defaultTokenAppKey {
|
||||||
|
return status.Errorf(codes.Unauthenticated, "app id or app key checksum failure")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
streamServerInterceptors = append(streamServerInterceptors, interceptor.StreamServerToken(checkToken))
|
||||||
|
}
|
||||||
|
|
||||||
|
// jwt token interceptor
|
||||||
|
//streamServerInterceptors = append(streamServerInterceptors, interceptor.StreamServerJwtAuth(
|
||||||
|
// // set ignore rpc methods(full path) for jwt token
|
||||||
|
// interceptor.WithAuthIgnoreMethods("/api.user.v1.User/Register", "/api.user.v1.User/Login"),
|
||||||
|
//))
|
||||||
|
|
||||||
// metrics interceptor
|
// metrics interceptor
|
||||||
if config.Get().App.EnableMetrics {
|
if config.Get().App.EnableMetrics {
|
||||||
streamServerInterceptors = append(streamServerInterceptors, interceptor.StreamServerMetrics())
|
streamServerInterceptors = append(streamServerInterceptors, interceptor.StreamServerMetrics())
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ func Test_service_userExample_methods(t *testing.T) {
|
|||||||
conn := getRPCClientConnForTest()
|
conn := getRPCClientConnForTest()
|
||||||
cli := serverNameExampleV1.NewUserExampleServiceClient(conn)
|
cli := serverNameExampleV1.NewUserExampleServiceClient(conn)
|
||||||
ctx, _ := context.WithTimeout(context.Background(), time.Second*3)
|
ctx, _ := context.WithTimeout(context.Background(), time.Second*3)
|
||||||
|
//ctx = interceptor.SetJwtTokenToCtx(ctx, "Bearer jwt-token-value")
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
@@ -9,12 +9,32 @@ import (
|
|||||||
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
|
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ---------------------------------- client ----------------------------------
|
||||||
|
|
||||||
|
// SetJwtTokenToCtx set the token to the context in rpc client side
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// ctx := SetJwtTokenToCtx(ctx, "Bearer jwt-token")
|
||||||
|
// cli.GetByID(ctx, req)
|
||||||
|
func SetJwtTokenToCtx(ctx context.Context, authorization string) context.Context {
|
||||||
|
md, ok := metadata.FromOutgoingContext(ctx)
|
||||||
|
if ok {
|
||||||
|
md.Set(headerAuthorize, authorization)
|
||||||
|
} else {
|
||||||
|
md = metadata.Pairs(headerAuthorize, authorization)
|
||||||
|
}
|
||||||
|
return metadata.NewOutgoingContext(ctx, md)
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------- server interceptor ----------------------------------
|
// ---------------------------------- server interceptor ----------------------------------
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
headerAuthorize = "authorization"
|
||||||
|
|
||||||
// auth Scheme
|
// auth Scheme
|
||||||
authScheme = "Bearer"
|
authScheme = "Bearer"
|
||||||
|
|
||||||
|
|||||||
@@ -95,3 +95,17 @@ func Test_defaultAuthOptions(t *testing.T) {
|
|||||||
o := defaultAuthOptions()
|
o := defaultAuthOptions()
|
||||||
assert.NotNil(t, o)
|
assert.NotNil(t, o)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetJWTTokenToCtx(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
expected := []string{"Bearer jwt-token-1"}
|
||||||
|
|
||||||
|
ctx = SetJwtTokenToCtx(ctx, expected[0])
|
||||||
|
md, _ := metadata.FromOutgoingContext(ctx)
|
||||||
|
assert.Equal(t, expected, md.Get(headerAuthorize))
|
||||||
|
|
||||||
|
expected[0] = "Bearer jwt-token-2"
|
||||||
|
ctx = SetJwtTokenToCtx(ctx, expected[0])
|
||||||
|
md, _ = metadata.FromOutgoingContext(ctx)
|
||||||
|
assert.Equal(t, expected, md.Get(headerAuthorize))
|
||||||
|
}
|
||||||
|
|||||||
@@ -251,7 +251,8 @@ service {{.TName}}Service {
|
|||||||
// to ensure that the front end and back end JSON naming is consistent.
|
// to ensure that the front end and back end JSON naming is consistent.
|
||||||
// (3) If the declared route path includes a variable, such as /api/v1/userExample/{id},
|
// (3) If the declared route path includes a variable, such as /api/v1/userExample/{id},
|
||||||
// the request parameter of the rpc method contains the route variable field and this field
|
// the request parameter of the rpc method contains the route variable field and this field
|
||||||
// must be annotated, such as int64 id = 1 [(tagger.tags) = "uri:\"id\"" ]
|
// must be annotated, such as int64 id = 1 [(tagger.tags) = "uri:\"id\""]; If the get method is used,
|
||||||
|
// the request parameters must be annotated with form, e.g. uint productID = 1 [(tagger.tags) = "form:\"productID\""].
|
||||||
|
|
||||||
|
|
||||||
// protoMessageCreateCode
|
// protoMessageCreateCode
|
||||||
|
|||||||
Reference in New Issue
Block a user