JWT tokens in Rust: jsonwebtoken library and authentication

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

JWT tokens in Rust: jsonwebtoken library

JSON Web Tokens (JWT) is an open standard (RFC 7519) for creating access tokens based on JSON. In the Rust ecosystem, one of the most popular and stable libraries for working with JWT is jsonwebtoken. It provides a full set of functions for creating, signing, verifying, and decoding JWT tokens, supporting both symmetric (HS256, HS384, HS512) and asymmetric (RS256, RS384, RS512, ES256, ES384) encryption algorithms.



Installation and setup

To get started, add the dependency to your project's Cargo.toml file:

[dependencies]jsonwebtoken = "9.3"serde = { version = "1.0", features = ["derive"] }chrono = "0.4"

The serde library is required for serializing and deserializing token data, and chrono simplifies working with timestamps (exp, iat, nbf).



Basic JWT structure

A JWT token consists of three parts: header, claims, and signature. In Rust, this is implemented through structures:

use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]struct Claims { sub: String, // subject (usually user ID) exp: usize, // expiration time (unix timestamp) iat: usize, // issued at (unix timestamp) role: String, // custom field}


Creating and signing a JWT token

Let's look at a complete example of creating a token using the HS256 algorithm (symmetric encryption):

use jsonwebtoken::{encode, Header, EncodingKey};use chrono::Utc;

fn create_jwt(user_id: &str, secret: &str) -> Result { let now = Utc::now().timestamp() as usize; let claims = Claims { sub: user_id.to_string(), exp: now + 3600, // token valid for 1 hour iat: now, role: "user".to_string(), };

let token = encode( &Header::default(), // defaults to HS256 &claims, &EncodingKey::from_secret(secret.as_bytes()), )?; Ok(token)}


Token verification and decoding

To verify the authenticity of a token, the decode function is used with the specified algorithm and secret key:

use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};

fn verify_jwt(token: &str, secret: &str) -> Result { let validation = Validation::new(Algorithm::HS256); let token_data = decode::( token, &DecodingKey::from_secret(secret.as_bytes()), &validation, )?; Ok(token_data.claims)}


Working with asymmetric algorithms (RS256)

For production environments, it is recommended to use asymmetric encryption. Example with RS256:

use jsonwebtoken::{encode, decode, Header, EncodingKey, DecodingKey, Validation, Algorithm};

// Creating a token with a private keyfn create_rs256_token(user_id: &str, private_key_pem: &str) -> Result> { let claims = Claims { sub: user_id.to_string(), exp: (Utc::now().timestamp() + 3600) as usize, iat: Utc::now().timestamp() as usize, role: "admin".to_string(), };

let token = encode( &Header::new(Algorithm::RS256), &claims, &EncodingKey::from_rsa_pem(private_key_pem.as_bytes())?, )?; Ok(token)}

// Verification with a public keyfn verify_rs256_token(token: &str, public_key_pem: &str) -> Result> { let mut validation = Validation::new(Algorithm::RS256); validation.validate_exp = true; // check expiration

let token_data = decode::( token, &DecodingKey::from_rsa_pem(public_key_pem.as_bytes())?, &validat

Recommendations