JSON Web Tokens (JWT) are an open, industry-standard RFC 7519 method for representing claims securely between two parties. In this article, we will explore how to work with JWTs in Go for authenticating users in your applications. Let's dive into creating, signing, and validating JWTs using Go.
Table of Contents
What is a JWT?
A JSON Web Token is essentially three components encoded in Base64 URL format and separated by dots: the header, the payload, and the signature. Here's what they each represent:
- Header: Contains metadata about the type of token and the signing algorithm used, such as
{ "alg": "HS256", "typ": "JWT" }. - Payload: Contains the claims. Claims are statements about an entity (usually, the user) and additional data.
- Signature: The signature is used to verify that the sender of the JWT is who it says it is and to ensure that the message wasn't changed in the process. This is created using the header and the payload.
Setting Up
We will use a popular package called github.com/dgrijalva/jwt-go for working with JWTs. You can install it by running:
go get -u github.com/dgrijalva/jwt-goCreating a JWT
Creating a JWT involves three main components: The header, the payload, and a secret signing key. You'll first define the claims you've decided your tokens to have. Here's a simple example of how you could create a JWT in Go:
package main
import (
"fmt"
"time"
"github.com/dgrijalva/jwt-go"
)
func main() {
// Define a sample secret key
var jwtKey = []byte("my_secret_key")
// Create a map to hold the claims
claims := &jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Hour * 72).Unix(),
Issuer: "my_app",
}
// Create a new token object, specifying the algorithm and the claims
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// Sign the token with our secret
tokenString, err := token.SignedString(jwtKey)
if err != nil {
panic(err)
}
fmt.Println("Your JWT: ", tokenString)
}Validating a JWT
Once you've sent a JWT to your client, they will send it back to you with each request to a secured endpoint. Validating and verifying a token consists of reconstructing the token with the payload, signature, and the secret.
package main
import (
"fmt"
"time"
"github.com/dgrijalva/jwt-go"
)
// Sample function to validate JWT
func validateToken(myToken string) {
var jwtKey = []byte("my_secret_key")
claims := &jwt.StandardClaims{}
token, err := jwt.ParseWithClaims(myToken, claims, func(token *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if err != nil {
fmt.Println("Token is invalid: ", err)
return
}
if token.Valid {
fmt.Println("Token is valid.", claims.Issuer)
} else {
fmt.Println("Token is not valid.")
}
}
func main() {
// Example use of the validateToken function
myToken := "your_jwt_string_here"
validateToken(myToken)
}Conclusion
In this article, we have discussed how to create and validate JWTs in Go. JWTs are a great way to maintain a stateless client-server communication. Ensure to implement them securely by keeping your signing keys safe and using well-chosen standard claims. Stay tuned for more advanced topics on JWTs where we'll cover custom claims and working with different algorithms.