authkestra-actix 0.1.2

Actix-web integration for the authkestra authentication framework
Documentation

authkestra-actix

Actix-web integration for authkestra.

This crate provides Actix-web specific extractors and utilities to integrate the authkestra authentication framework into Actix applications.

Features

  • Extractors: Easily access validated sessions or JWT claims in your request handlers.
  • OAuth2 Helpers: Streamlined functions for initiating login, handling callbacks, and logging out.
  • Session Management: Integration with authkestra-session for server-side session storage.

Usage

Add this to your Cargo.toml:

[dependencies]
authkestra-actix = "0.1.2"
authkestra-session = "0.1.1"
authkestra-token = "0.1.2"
actix-web = "4"

Extractors

AuthSession

Extracts a validated session from a cookie. Requires Arc<dyn SessionStore> and SessionConfig to be registered in app_data.

use authkestra_actix::AuthSession;
use actix_web::{get, HttpResponse};

#[get("/profile")]
async fn profile(AuthSession(session): AuthSession) -> HttpResponse {
    HttpResponse::Ok().json(session.identity)
}

AuthToken

Extracts and validates a JWT from the Authorization: Bearer <token> header. Requires Arc<TokenManager> to be registered in app_data.

use authkestra_actix::AuthToken;
use actix_web::{get, HttpResponse};

#[get("/api/data")]
async fn protected_api(AuthToken(claims): AuthToken) -> HttpResponse {
    HttpResponse::Ok().json(claims)
}

Jwt<T> (Offline Validation)

Extracts and validates a JWT against a remote JWKS (e.g., Google, Auth0). Requires Arc<JwksCache> and jsonwebtoken::Validation to be registered in app_data.

use authkestra_actix::Jwt;
use authkestra_guard::jwt::JwksCache;
use actix_web::{get, HttpResponse, web};
use serde::Deserialize;
use std::sync::Arc;

#[derive(Deserialize)]
struct MyClaims {
    sub: String,
    // ...
}

#[get("/api/external")]
async fn external_api(Jwt(claims): Jwt<MyClaims>) -> HttpResponse {
    HttpResponse::Ok().json(claims)
}

OAuth2 Helpers

The crate provides helpers to manage the OAuth2 flow lifecycle.

SPA vs Server-Side Rendering

For SPA (Single Page Application) use cases where you want to receive a JWT on the frontend:

  1. The redirect_uri in your OAuth provider configuration should point to a frontend route (e.g., https://myapp.com/callback).
  2. Your frontend route should extract the code and state from the URL.
  3. The frontend then performs a POST (or GET) request to your backend's callback endpoint (e.g., /api/auth/callback) with these parameters.
  4. The backend uses handle_oauth_callback_jwt to exchange the code for a JWT and returns it to the frontend.
use authkestra_actix::{initiate_oauth_login, handle_oauth_callback, logout, SessionConfig, OAuthCallbackParams};
use actix_web::{web, HttpRequest, HttpResponse, get};
use std::sync::Arc;

// 1. Initiate Login
#[get("/login")]
async fn login(flow: web::Data<OAuth2Flow>, config: web::Data<SessionConfig>) -> HttpResponse {
    initiate_oauth_login(&flow, &config, &["user:email"])
}

// 2. Handle Callback (Server-Side Session)
#[get("/callback")]
async fn callback(
    req: HttpRequest,
    params: web::Query<OAuthCallbackParams>,
    flow: web::Data<OAuth2Flow>,
    store: web::Data<Arc<dyn SessionStore>>,
    config: web::Data<SessionConfig>,
) -> Result<HttpResponse, actix_web::Error> {
    handle_oauth_callback(
        req,
        &flow,
        params.into_inner(),
        store.get_ref().clone(),
        config.get_ref().clone(),
        "/dashboard"
    ).await
}

// 3. Logout
#[get("/logout")]
async fn sign_out(
    req: HttpRequest,
    store: web::Data<Arc<dyn SessionStore>>,
    config: web::Data<SessionConfig>,
) -> Result<HttpResponse, actix_web::Error> {
    logout(req, store.get_ref().clone(), config.get_ref().clone(), "/").await
}

Setup

To use the extractors and helpers, you must configure your Actix app with the necessary data:

use actix_web::{web, App, HttpServer};
use authkestra_actix::SessionConfig;
use authkestra_session::MemoryStore;
use authkestra_token::TokenManager;
use std::sync::Arc;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let session_store: Arc<dyn SessionStore> = Arc::new(MemoryStore::new());
    let token_manager = Arc::new(TokenManager::new("your-secret".to_string()));
    let session_config = SessionConfig::default();

    HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(session_store.clone()))
            .app_data(web::Data::new(token_manager.clone()))
            .app_data(web::Data::new(session_config.clone()))
            // ... routes
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

Part of authkestra

This crate is part of the authkestra workspace.