The steps of implementing JWT authentication in Go by ES0en zero are explained in detail

  • 2020-11-18 06:17:30
  • OfStack

About WHAT JWT is, you can have a look at the official website, 1 sentence to introduce: it can realize the server stateless authentication scheme, is also the most popular cross-domain authentication solution.

To implement JWT certification, we need to break it down into two steps

The client gets JWT token. The server brings JWT token authentication to the client.

1. Client obtains JWT Token

We define a protocol for the client to call to get JWT token, we create a new directory jwt and execute it in the directory goctl api -o jwt.api , change the generated jwt. api to the following:


type JwtTokenRequest struct {
}

type JwtTokenResponse struct {
 AccessToken string `json:"access_token"`
 AccessExpire int64 `json:"access_expire"`
 RefreshAfter int64 `json:"refresh_after"` //  Client refresh is recommended token Absolute time of 
}

type GetUserRequest struct { 
 UserId string `json:"userId"`
}

type GetUserResponse struct {
 Name string `json:"name"`
}

service jwt-api {
 @handler JwtHandler
 post /user/token(JwtTokenRequest) returns (JwtTokenResponse)
}

@server(
 jwt: JwtAuth
)
service jwt-api {
 @handler JwtHandler
 post /user/info(GetUserRequest) returns (GetUserResponse)
}

In the service jwt directory: goctl api go -api jwt.api -dir .
Open the jwtlogic.go file and modify it func (l *JwtLogic) Jwt(req types.JwtTokenRequest) (*types.JwtTokenResponse, error) { The methods are as follows:


func (l *JwtLogic) Jwt(req types.JwtTokenRequest) (*types.JwtTokenResponse, error) {
	var accessExpire = l.svcCtx.Config.JwtAuth.AccessExpire

	now := time.Now().Unix()
	accessToken, err := l.GenToken(now, l.svcCtx.Config.JwtAuth.AccessSecret, nil, accessExpire)
	if err != nil {
		return nil, err
	}

	return &types.JwtTokenResponse{
 AccessToken: accessToken,
 AccessExpire: now + accessExpire,
 RefreshAfter: now + accessExpire/2,
 }, nil
}

func (l *JwtLogic) GenToken(iat int64, secretKey string, payloads map[string]interface{}, seconds int64) (string, error) {
	claims := make(jwt.MapClaims)
	claims["exp"] = iat + seconds
	claims["iat"] = iat
	for k, v := range payloads {
		claims[k] = v
	}

	token := jwt.New(jwt.SigningMethodHS256)
	token.Claims = claims

	return token.SignedString([]byte(secretKey))
}

Before starting the service, we need to modify the etc/ jwt-ES35en.yaml file as follows:


Name: jwt-api
Host: 0.0.0.0
Port: 8888
JwtAuth:
 AccessSecret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 AccessExpire: 604800

Start the server and test the token you get.


➜ curl --location --request POST '127.0.0.1:8888/user/token'
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDEyNjE0MjksImlhdCI6MTYwMDY1NjYyOX0.6u_hpE_4m5gcI90taJLZtvfekwUmjrbNJ-5saaDGeQc","access_expire":1601261429,"refresh_after":1600959029}

2. Server validates JWT token

Approved in the api file jwt: JwtAuth The service of the tag indicates that the jwt authentication is activated. Can read rest/handler/authhandler go jwt know server implementation file. Modify getuserlogic.go as follows:


func (l *GetUserLogic) GetUser(req types.GetUserRequest) (*types.GetUserResponse, error) {
	return &types.GetUserResponse{Name: "kim"}, nil
}

We do not take JWT Authorization header request header test, return http status code is 401, as expected.


➜ curl -w "\nhttp: %{http_code} \n" --location --request POST '127.0.0.1:8888/user/info' \
--header 'Content-Type: application/json' \
--data-raw '{
 "userId": "a"
}'

http: 401

Add Authorization header request header tests.


➜ curl -w "\nhttp: %{http_code} \n" --location --request POST '127.0.0.1:8888/user/info' \
--header 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDEyNjE0MjksImlhdCI6MTYwMDY1NjYyOX0.6u_hpE_4m5gcI90taJLZtvfekwUmjrbNJ-5saaDGeQc' \
--header 'Content-Type: application/json' \
--data-raw '{
 "userId": "a"
}'
{"name":"kim"}
http: 200

To sum up: JWT certification based on ES76en-ES77en is completed. When deploying in the real production environment, AccessSecret, AccessExpire and RefreshAfter are configured through the configuration file according to the business scenario. RefreshAfter is to tell the client when it is time to refresh JWT token.

3. Project address

https://github.com/tal-tech/go-zero

conclusion


Related articles: