In today's Internet application development, security is receiving more and more attention. JSON Web Tokens (JWT) have become one of the common authentication and authorization schemes in most web API designs. JWT is an open standard (RFC 7519) that defines a compact and self-contained way to securely communicate information between parties.
Go language is a very powerful server-side programming language, and it is very easy to implement JWT easily. In this article, we will introduce how to implement JWT in Golang.
1.Introduce dependencies
First, you need to introduce the following libraries:
import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/pem" "errors" "fmt" "time" "github.com/dgrijalva/jwt-go" )
2. Create a key file
First, you need to create a private key file. Use the following command to generate the private key file:
openssl genrsa -out app.rsa 1024
This will generate a 1024-bit RSA key named app.rsa
. We will use this key to generate the JWT.
Now, we can create the JWT token using the following code:
func GenerateJWT() (string, error) { token := jwt.New(jwt.SigningMethodHS256) claims := token.Claims.(jwt.MapClaims) claims["authorized"] = true claims["user"] = "user@example.com" claims["exp"] = time.Now().Add(time.Hour * 1).Unix() tokenString, err := token.SignedString([]byte("secret")) if err != nil { return "", err } return tokenString, nil }
This function creates the JWT token using the HS256 algorithm . First, we create a new JWT token object. We then add the statement to its claims. In this example, we declare that "Authorization" is set to "True", the user is set to "user@example.com", and the JWT's expiration time is set to 1 hour later. Finally, we sign the JWT using the provided "secret" ("secret" in this example) and return that string.
We can use the following code to parse the JWT token:
func ParseJWT(tokenString string) (jwt.MapClaims, error) { token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return []byte("secret"), nil }) if err != nil { return nil, err } if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { return claims, nil } return nil, errors.New("invalid token") }
The function accepts the JWT token string and then Try parsing the JWT. Here we use HS256 algorithm to decrypt jwt. First, we need to verify whether the Token is signed using the HMAC algorithm, otherwise an error will be returned. Next, we return an encryption key ("secret" in this example). When parsing is successful, the function returns a verified and unexpired claim. If parsing fails, the function returns an error message.
In addition to the HS256 algorithm, there are many other encryption algorithms that you can use to encrypt the JWT payload. For example, a JWT signed using the RSA algorithm is more secure than using the HS256 algorithm. Here is a way to generate a JWT token using the RSA algorithm:
func GenerateJWT() (string, error) { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return "", err } token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{ "authorized": true, "user": "user@example.com", "exp": time.Now().Add(time.Hour * 1).Unix(), }) tokenString, err := token.SignedString(privateKey) if err != nil { return "", err } return tokenString, nil }
Here, we first generate a 2048-bit RSA private key. We then sign the JWT token using the RS256 algorithm. Finally, we sign the JWT token using the private key.
When parsing the JWT token, a different approach also needs to be taken:
func ParseJWT(tokenString string) (jwt.MapClaims, error) { publicKey := ` -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArtpZKxF+1MDwcJ61KeJt GjHYiAL46jEewsjF9oBz59J2y5/v/tE/RQjJjOtGvLQ5LfPYBK+j+Z6QIwU1ZzCJ I0MT5mn81znZCsy7zcZI7+kRPG8Fk5JzKM2ug7RAuYqnOjArL8+V+uS4Moh2RWdN yZizvjajzKtbH5zLC49Dd3X/SrjzPQpzt8HY4Z7YxYej8/Akl3nxdx9Q/OPG2NYP xtflmpLLJc7roqkfVwwMQeC1apHr/klI3FHPvK/pzBoUCUOpTfnyvHg8O1+PyMKJ CldHEhuzUsTR5jM5fXv0M4+vL36QO8k1WhO4gcQTD6X7fIWqFhfrRM/jreG+bv8c 7wIDAQAB -----END PUBLIC KEY----- ` block, _ := pem.Decode([]byte(publicKey)) if block == nil { return nil, errors.New("failed to decode PEM block containing public key") } pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return pub, nil }) if err != nil { return nil, err } if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { return claims, nil } return nil, errors.New("invalid token") }
In this function, we need to extract the RSA public key first and then pass it to the jwt.Parse function. When parsing the token, the jwt-go library will automatically use the public key for verification. Note that the public key used here is provided in PKIX format. You can use a tool like OpenSSL to export the PEM public key to PKIX format.
6. Summary
In this article, we introduced how to create and parse JWT tokens in Golang using HS256 and RS256 algorithms. This is a common authentication and authorization scheme that you can use in future web applications. Hope this article is helpful to you.
The above is the detailed content of golang implements jwt. For more information, please follow other related articles on the PHP Chinese website!