Gin tutorial yi comes (said good finale?) , this time mainly to explain some problems and solutions existing in JWT. If you don’t already know what JWT is, it’s recommended that you find out, or check out the previous article.

💊 The problem

When I wrote JWT last time, I had a discussion with my friends in the group. Some of my friends raised some questions: How should users change their passwords or cancel their accounts?

Yeah, what do we do?

We all know whether JWT is valid or not depends on the expiration time, and the server does not save the user JWT, that is, once the JWT is issued, the server loses control over it and has to wait for it to expire. If this is the case, then the previous JWT can still be used after the user changes the password or logs out, which poses a security risk.

So, I silently opened a hundred degrees (GU) (GE)

🙄 🙄 🙄 🙄 🙄 🙄

Why did you save JWT in Redis?

What is this operation? Once the server saves the JWT, what JWT is used? Ordinary token is perfectly ok, why bother?

These are the problems we have with JWT.

🀄 Solve the problem

If there is a problem, it must be solved.

Again, review the JWT usage process.

  1. The browser sends a login request and submits the account and password to the server.

  2. The server creates the JWT and encrypts it (not all of it, just VERIFY SIGNATURE);

  3. Return the JWT to the browser;

  4. Access the interface that requires authorization, carrying the JWT in the Header;

  5. Verify JWT and get JWT from JWT;

  6. Response browser.

The above six steps are the process used by JWT. The server only does two steps, generating and validating the JWT. And we solve the problems mentioned above, on the server side to solve.

As we all know, during encryption, the server will save a KEY, which is needed for verification and decryption. This KEY is the KEY to solve the problem.

If we set the key as dynamic, the key will be changed when the user password is changed or logged out, then the JWT issued before cannot be decrypted with the new key, which means that the previous key has been invalid. The dynamic key should be independent. The key of each user should be different. The key of the user is only responsible for the JWT of the user.

Therefore, the problem seems to have been solved, we can set a separate field in the database user table to identify, every time there is a password change or account logout, only need to change this field to ensure that the previous JWT is invalid. Or use the user’s password as the key.

Part of the code

UserHandler.go

// Encrypt with password and reserved fields
var jwtSecret = []byte(config.Secret + u.Password)
token, err := tokenClaims.SignedString(jwtSecret)
Copy the code

Where config.Secret is the fixed key on our server.

Auth.go

// Split the carrier
payload := strings.Split(token, ".")
bytes, e := jwt.DecodeSegment(payload[1])

ife ! =nil {
	println(e.Error())
}
content := ""
for i := 0; i < len(bytes); i++ {
	content += string(bytes[i])
}
split := strings.Split(content, ",")
id := strings.SplitAfter(split[2].":")
i := strings.Split(id[1]."\\u")
i = strings.Split(i[1]."\" ")

ID, err := strconv.Atoi(i[0])
iferr ! =nil {
	println(err.Error())
}

user := model.User{}
user.ID = uint(ID)
u := model.User.QueryById(user)
jwtToken, err := jwt.ParseWithClaims(token, &jwt.StandardClaims{},
	func(token *jwt.Token) (i interface{}, e error) {
		return []byte(config.Secret + u.Password), nil
	})
Copy the code

I’m not going to show you all the code here. Check out Github gin_jwT_2.

Personal public account

Welcome to your attention.