Claude Code Plugins

Community-maintained marketplace

Feedback

rust-backend-auth

@caioniehues/dotfiles
0
0

Implements authentication and authorization for Rust backend services using JWT, password hashing, sessions, and middleware patterns. Use when building auth systems, implementing login/logout, protecting routes, hashing passwords, or working with JWT tokens in Axum/Tower applications.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name rust-backend-auth
description Implements authentication and authorization for Rust backend services using JWT, password hashing, sessions, and middleware patterns. Use when building auth systems, implementing login/logout, protecting routes, hashing passwords, or working with JWT tokens in Axum/Tower applications.
Provides production-ready authentication patterns for Rust backend services. Covers JWT token creation/validation, secure password hashing with Argon2, and auth middleware that injects user context. 1. **Password Storage**: Use Argon2id with random salts. Store the PHC string. 2. **Token Validation**: Always validate exp, iss, aud claims. Handle clock skew. 3. **Middleware Design**: Inject authenticated user via request extensions. Fail closed. **JWT Encoding and Decoding**
use jsonwebtoken::{encode, decode, Header, EncodingKey, DecodingKey, Validation, Algorithm};

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

pub struct JwtService {
    encoding_key: EncodingKey,
    decoding_key: DecodingKey,
    validation: Validation,
}

impl JwtService {
    pub fn new(secret: &[u8], issuer: &str) -> Self {
        let mut validation = Validation::new(Algorithm::HS256);
        validation.set_issuer(&[issuer]);
        validation.leeway = 60;

        Self {
            encoding_key: EncodingKey::from_secret(secret),
            decoding_key: DecodingKey::from_secret(secret),
            validation,
        }
    }

    pub fn create_token(&self, claims: &Claims) -> Result<String, AuthError> {
        encode(&Header::default(), claims, &self.encoding_key)
            .map_err(|_| AuthError::TokenCreation)
    }

    pub fn validate_token(&self, token: &str) -> Result<Claims, AuthError> {
        decode::<Claims>(token, &self.decoding_key, &self.validation)
            .map(|data| data.claims)
            .map_err(|err| match *err.kind() {
                ErrorKind::ExpiredSignature => AuthError::TokenExpired,
                _ => AuthError::InvalidToken,
            })
    }
}
**Argon2 Password Hashing**
use argon2::{
    password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
    Argon2,
};

fn hash_password(password: &str) -> Result<String, argon2::password_hash::Error> {
    let salt = SaltString::generate(&mut OsRng);
    let argon2 = Argon2::default();
    Ok(argon2.hash_password(password.as_bytes(), &salt)?.to_string())
}

fn verify_password(password: &str, hash: &str) -> bool {
    let parsed_hash = match PasswordHash::new(hash) {
        Ok(h) => h,
        Err(_) => return false,
    };
    Argon2::default().verify_password(password.as_bytes(), &parsed_hash).is_ok()
}
**Auth Middleware**
pub async fn auth_middleware(
    Extension(jwt_service): Extension<Arc<JwtService>>,
    mut req: Request,
    next: Next,
) -> Result<Response, StatusCode> {
    let auth_header = req.headers()
        .get(header::AUTHORIZATION)
        .and_then(|h| h.to_str().ok())
        .and_then(|h| h.strip_prefix("Bearer "));

    let token = auth_header.ok_or(StatusCode::UNAUTHORIZED)?;
    let claims = jwt_service.validate_token(token).map_err(|_| StatusCode::UNAUTHORIZED)?;

    req.extensions_mut().insert(AuthenticatedUser::from(claims));
    Ok(next.run(req).await)
}
- [ ] Secrets from environment variables, never hardcoded - [ ] Algorithm explicitly specified in Validation - [ ] exp, iss, aud validated on every decode - [ ] Argon2id for password hashing - [ ] Generic error messages ("Invalid credentials") - [ ] Rate limiting on auth endpoints - [ ] Passwords hashed with Argon2id - [ ] JWT tokens include sub, exp, iat, iss claims - [ ] Auth middleware injects user into extensions - [ ] Protected routes return 401 without valid token - [ ] All secrets from environment variables