Авторизация и аутентификация в Rust: библиотеки и практические примеры

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Авторизация и аутентификация в Rust: от JWT до сессий

В мире системного и веб-программирования Rust завоевал репутацию безопасного и быстрого языка. Однако при создании веб-приложений разработчики часто сталкиваются с задачей реализации аутентификации (проверки подлинности пользователя) и авторизации (проверки прав доступа). В этой статье мы рассмотрим ключевые библиотеки и подходы для реализации этих механизмов в Rust, а также приведём практические примеры кода.

Основные концепции аутентификации и авторизации

Прежде чем перейти к инструментам, важно разграничить понятия:

  • Аутентификация — процесс проверки, что пользователь тот, за кого себя выдаёт. Обычно выполняется с помощью логина/пароля, токенов или биометрии.
  • Авторизация — определение того, какие ресурсы и действия доступны аутентифицированному пользователю. Часто реализуется через роли (администратор, модератор, пользователь) или права доступа.

В Rust оба процесса можно реализовать как на низком уровне (ручное управление токенами), так и с помощью готовых библиотек.

Популярные библиотеки для аутентификации в Rust

Для работы с сессиями и токенами в Rust существует несколько зрелых решений:

  • actix-identity — для управления сессиями в веб-фреймворке Actix-web. Поддерживает cookie-сессии и Redis.
  • jsonwebtoken — библиотека для работы с JWT (JSON Web Tokens). Позволяет создавать, подписывать и верифицировать токены.
  • argon2 — реализация алгоритма хеширования паролей Argon2, рекомендованного OWASP.
  • bcrypt — классическая библиотека для хеширования паролей.

Ниже мы рассмотрим каждый инструмент на примере.

Пример 1: Аутентификация с JWT и jsonwebtoken

JWT — один из самых популярных способов аутентификации в REST API. Токен содержит утверждения (claims) и подписывается секретным ключом. Рассмотрим базовую реализацию с помощью библиотеки jsonwebtoken.

// cargo add jsonwebtoken serde
use jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};
use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]
struct Claims {
    sub: String,   // идентификатор пользователя
    exp: usize,    // время истечения (UNIX timestamp)
    role: String,  // роль пользователя
}

fn create_token(user_id: &str, role: &str) -> Result<String, jsonwebtoken::errors::Error> {
    let claims = Claims {
        sub: user_id.to_owned(),
        exp: (chrono::Utc::now() + chrono::Duration::hours(24)).timestamp() as usize,
        role: role.to_owned(),
    };
    encode(
        &Header::default(),
        &claims,
        &EncodingKey::from_secret(b"ваш_секретный_ключ")
    )
}

fn verify_token(token: &str) -> Result<Claims, jsonwebtoken::errors::Error> {
    let token_data = decode::<Claims>(
        token,
        &DecodingKey::from_secret(b"ваш_секретный_ключ"),
        &Validation::default()
    )?;
    Ok(token_data.claims)
}

В этом примере мы создаём токен на 24 часа, содержащий ID пользователя и его роль. Функция verify_token проверяет подпись и возвращает claims, которые можно использовать для авторизации.

Пример 2: Хеширование паролей с Argon2

Никогда не храните пароли в открытом виде! Используйте Argon2 — современный и безопасный алгоритм хеширования.

// cargo add argon2
use argon2::{Argon2, PasswordHash, PasswordHasher, PasswordVerifier};
use argon2::password_hash::{SaltString, rand_core::OsRng};

fn hash_password(password: &str) -> String {
    let salt = SaltString::generate(&mut OsRng);
    let argon2 = Argon2::default();
    argon2.hash_password(password.as_bytes(), &salt)
        .expect("Ошибка хеширования")
        .to_string()
}

fn verify_password(password: &str, hash: &str) -> bool {
    let parsed_hash = PasswordHash::new(hash).expect("Неверный формат хеша");
    Argon2::default().verify_password(password.as_bytes(), &parsed_hash).is_ok()
}

Функция hash_password генерирует соль и возвращает строку хеша. verify_password проверяет пароль против сохранённого хеша.

Пример 3: Сессии в Actix-web с actix-identity

Для веб-приложений с традиционными сессиями удобно использовать

Рекомендаций