Home  >  Article  >  Backend Development  >  golang implements jwt

golang implements jwt

WBOY
WBOYOriginal
2023-05-22 10:31:36927browse

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"
)
  • crypto/rsa: Contains the functions of generating and parsing RSA public and private keys .
  • crypto/x509: Contains certificate functions in PKIX format
  • encoding/base64: used to encode and decode parts of the JWT
  • encoding/pem: used to extract and Store certificates in PEM format
  • errors: used to process returned error messages
  • fmt: standard formatting function
  • time: standard time function
  • github .com/dgrijalva/jwt-go: JWT’s main dependency

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.

  1. Generate JWT token

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.

  1. Parsing JWT token

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.

  1. More advanced encryption methods

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:Is golang easy to use?Next article:Is golang easy to use?