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