Authentication

Auth middleware is used to authenticate requests. Only those authenticated could be processed. At the same time, one can setup white list with selector middleware.

Usage

server

User should provider a jwt.Keyfunc as parameter.

  • http
  1. httpSrv := http.NewServer(
  2. http.Address(":8000"),
  3. http.Middleware(
  4. jwt.Server(func(token *jwtv4.Token) (interface{}, error) {
  5. return []byte(testKey), nil
  6. }),
  7. ),
  8. )
  • grpc
  1. grpcSrv := grpc.NewServer(
  2. grpc.Address(":9000"),
  3. grpc.Middleware(
  4. jwt.Server(func(token *jwtv4.Token) (interface{}, error) {
  5. return []byte(testKey), nil
  6. }),
  7. ),
  8. )

client

User should provider a jwt.Keyfunc as parameter.

  • http
  1. conn, err := http.NewClient(
  2. context.Background(),
  3. http.WithEndpoint("127.0.0.1:8000"),
  4. http.WithMiddleware(
  5. jwt.Client(func(token *jwtv4.Token) (interface{}, error) {
  6. return []byte(serviceTestKey), nil
  7. }),
  8. ),
  9. )
  • grpc
  1. con, _ := grpc.DialInsecure(
  2. context.Background(),
  3. grpc.WithEndpoint("xxx.xxx.domain"),
  4. grpc.WithMiddleware(
  5. jwt.Client(func(token *jwtv4.Token) (interface{}, error) {
  6. return []byte(serviceTestKey), nil
  7. }),
  8. ),
  9. )

Options

WithSigningMethod()

Used to set the sigining method.Works for server and client.

For examples:

  1. import jwtv4 "github.com/golang-jwt/jwt/v4"
  2. jwt.WithSigningMethod(jwtv4.SigningMethodHS256)

WithClaims()

Used to set the claims.

For examples:

  • For client:
  1. claims := &jwtv4.StandardClaims{}
  2. jwt.WithClaims(func()jwtv4.Claims{return claims})
  • For server:

Caution:server setting is different to client. server must return a new object in order to avoid concurrent write problems.

  1. jwt.WithClaims(func()jwtv4.Claims{return &jwtv4.StandardClaims{}})

Example

A simple example, includes the use of server and client.

In particular, client is set to visit a service listening the port 9001. And that service should set a key as the same as the client one named serviceTestKey.

  1. con, _ := grpc.DialInsecure(
  2. context.Background(),
  3. grpc.WithEndpoint("dns:///127.0.0.1:9001"), // Services for local port 9001
  4. grpc.WithMiddleware(
  5. jwt.Client(func(token *jwtv4.Token) (interface{}, error) {
  6. return []byte(serviceTestKey), nil
  7. }),
  8. ),
  9. )

Extract Users’ Information

In summary, one could get users’ information by calling interface jwt.FromContext(ctx).

Under the hook, after processing by the middleware, the claims information would be stored into the context. One should assert the claims as the type that is used to create the token before using it.

Source code:

  1. func FromContext(ctx context.Context) (token jwt.Claims, ok bool)

White List Demo

With selector middleware, one could setup white list. Ref: https://github.com/go-kratos/beer-shop/blob/a29eae57a9baeae9969e9a7d418ff677cf494a21/app/shop/interface/internal/server/http.go#L41.

Generate JWT Token

Caution:The generated JWT Token is only used to the authentication between the client and the service. There are no interface that generated token for other use case. So user should write thire own code to satify thire use case.

There only one thing that the user should guarantee: client and service should use same sigining method and key. The external information, such as user information, could be set with WithClaims() option.

Ref: https://github.com/go-kratos/kratos/blob/9e66ac2f5bcb9ab18d9b8d378c5b3233c7bb0a73/middleware/auth/jwt/jwt.go#L148