We are using two types of tokens for authentication in the applications,
Keep in mind that, these tokens are not only JWT-specific. They provide a way to authorize resources. We can create these tokens using JWT or any other format.
After the first access token has run out, the refresh token is used to authenticate the user. Without user intervention, this takes place in the background, enhancing user experience without compromising security. Refresh tokens do not grant the user any further access over what was first permitted.
If you want to know more about it, this thread will be helpful to you.
Security is mostly a matter of human behavior, and behavior can be defined by habits. Improve your habits with justly.
JWT(JSON web token) is a token format used for authentication in any application. jwt.io provides a web interface to check the JWT tokens and a user guide for understanding the token structure.
JWT tokens contain three parts:
We will implement Golang JWT authentication using a go-jwt package.
We can simply relate the JWT terminologies with the residential locking system as below,
For generating tokens, we need a separate secret key for both tokens (or the same key can also be used for both tokens). You can generate it with HSA 256 OR RS256 encryption. It should at least be 32 characters long, but longer is better.
Next, define claims. go-jwt has its standard claims for JWT. But we can create custom claims as the below struct,
type JWTData struct {
jwt.StandardClaims
CustomClaims map[string]string `json:"custom_claims"`
}
Let’s generate tokens using these claims,
import "github.com/golang-jwt/jwt/v4"
func GenerateJWTAccessToken(userId string, email string) (string, error) {
// prepare claims for token
claims := JWTData{
StandardClaims: jwt.StandardClaims{
// set token lifetime in timestamp
ExpiresAt: time.Now().Add(time.Duration(tokenLifeTime)).Unix(),
},
// add custom claims like user_id or email,
// it can vary according to requirements
CustomClaims: map[string]string{
"user_id": userId,
"email": email,
},
}
// generate a string using claims and HS256 algorithm
tokenString := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// sign the generated key using secretKey
token, err := tokenString.SignedString(secretKey)
return token, err
}
token
which will be a JWT token containing a header, signature, and payload. You can check the token at jwt.io.
The same method can be used to generate refresh tokens with a greater lifespan.
For verifying the authorized resources, we need to validate the token first.
The below code will be used to validate tokens,
claims := &JWTData{}
_, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) {
return secretKey, nil
})
func(token *jwt.Token) (interface{}, error) {
return secretKey, nil
}
We can validate the tokens by claims ExpiresAt
. It also has custom claims user_id
and email
. You can check whether they are present in your database, and authorize users with a given token.
Here is the code for errors if the token is not valid,
if err != nil {
// check whether error is validation error or not
if validationErr, ok := err.(*jwt.ValidationError); ok {
// Token is malformed
if validationErr.Errors & jwt.ValidationErrorMalformed != 0 {
return "Token is malformed"
} else if validationErr.Errors & (jwt.ValidationErrorExpired | jwt.ValidationErrorNotValidYet) != 0 {
// Token is either expired or not active yet
return "Token is either expired or not active yet"
} else {
return "Other err"
}
} else {
return "Other err"
}
}
As we know, a refresh token will be used to renew the access token.
Here is the flow of getting access token from refresh token,
Note: You can pass refresh-token in the header or in form-data whatever is preferable.
_, err := jwt.ParseWithClaims(refreshToken, claims, func(token *jwt.Token) (interface{}, error) {
return secretKey, nil
})
same scope
and defined lifetime
.Consider a scenario, where the refresh-token lifetime is 1 month and the user has not used the app for 2 months. A refresh token expires if not used within the given time, after which a new refresh token and access token need to be requested again. Otherwise it will be refreshed with the access token.
JWT authentication provides security between two parties using signed tokens.
It is a widely used format for authentication. I have explained it to Golang, but the flow will be the same for other languages also like javascript or PHP.
We’re Grateful to have you with us on this journey!
Suggestions and feedback are more than welcome!
Please reach us at Canopas Twitter handle @canopas_eng with your content or feedback. Your input enriches our content and fuels our motivation to create more valuable and informative articles for you.
That’s it for today, Keep reading for the best.
Get started today
Let's build the next
big thing!
Let's improve your business's digital strategy and implement robust mobile apps to achieve your business objectives. Schedule Your Free Consultation Now.
Get Free ConsultationGet started today
Let's build the next big thing!
Let's improve your business's digital strategy and implement robust mobile apps to achieve your business objectives. Schedule Your Free Consultation Now.
Get Free Consultation