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.

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 must return a new object in order to avoid concurrent write problems.

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

Demo

A simple demo

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"),
  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/9743ad8d32890258177e0335d1a0741e9d45833e/middleware/auth/jwt/jwt.go#L124