
The official community-maintained Clerk SDK for Rust
For more detailed documentation, please reference the below links:
This SDK is updated frequently to keep up with any changes to the actual Clerk API. If you see anything that needs updating or is not inline with the official Clerk api, please open an issue!
Examples
Check out examples in the /examples directory
Using a traditional http request to a valid clerk endpoint:
use tokio;
use clerk_rs::{clerk::Clerk, ClerkConfiguration, endpoints::ClerkGetEndpoint};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ClerkConfiguration::new(None, None, Some("sk_test_key".to_string()), None);
let client = Clerk::new(config);
let res = client.get(ClerkGetEndpoint::GetUserList).await?;
Ok(())
}
Using a clerk-rs method:
use tokio;
use clerk_rs::{clerk::Clerk, ClerkConfiguration, apis::emails_api::Email};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ClerkConfiguration::new(None, None, Some("sk_test_key".to_string()), None);
let client = Clerk::new(config);
Email::create(&client, Some(your_clerk_email));
Ok(())
}
Protecting a actix-web endpoint with Clerk.dev:
With the actix feature enabled:
use actix_web::{web, App, HttpServer, Responder};
use clerk_rs::{
clerk::Clerk,
validators::{actix::ClerkMiddleware, jwks::MemoryCacheJwksProvider},
ClerkConfiguration,
};
async fn index() -> impl Responder {
"Hello world!"
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
let config = ClerkConfiguration::new(None, None, Some("your_secret_key".to_string()), None);
let clerk = Clerk::new(config);
App::new()
.wrap(ClerkMiddleware::new(MemoryCacheJwksProvider::new(clerk), None, true))
.route("/index", web::get().to(index))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
Protecting a axum endpoint with Clerk.dev:
With the axum feature enabled:
use axum::{routing::get, Router};
use clerk_rs::{
clerk::Clerk,
validators::{axum::ClerkLayer, jwks::MemoryCacheJwksProvider},
ClerkConfiguration,
};
async fn index() -> &'static str {
"Hello world!"
}
#[tokio::main]
async fn main() -> std::io::Result<()> {
let config = ClerkConfiguration::new(None, None, Some("your_secret_key".to_string()), None);
let clerk = Clerk::new(config);
let app = Router::new()
.route("/index", get(index))
.layer(ClerkLayer::new(MemoryCacheJwksProvider::new(clerk), None, true));
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await?;
axum::serve(listener, app).await
}
Protecting a rocket endpoint with Clerk.dev:
With the rocket feature enabled:
use clerk_rs::{
clerk::Clerk,
validators::{
jwks::MemoryCacheJwksProvider,
rocket::{ClerkGuard, ClerkGuardConfig},
},
ClerkConfiguration,
};
use rocket::{
get, launch, routes,
serde::{Deserialize, Serialize},
};
#[derive(Serialize, Deserialize)]
struct Message {
content: String,
}
#[get("/")]
fn index(jwt: ClerkGuard<MemoryCacheJwksProvider>) -> &'static str {
"Hello world!"
}
#[launch]
fn rocket() -> _ {
let config = ClerkConfiguration::new(None, None, Some("sk_test_F9HM5l3WMTDMdBB0ygcMMAiL37QA6BvXYV1v18Noit".to_string()), None);
let clerk = Clerk::new(config);
let clerk_config = ClerkGuardConfig::new(
MemoryCacheJwksProvider::new(clerk),
None,
true, );
rocket::build().mount("/", routes![index]).manage(clerk_config)
}
Protecting a Poem endpoint with Clerk
With the poem feature enabled and poem v3 installed:
use clerk_rs::{
clerk::Clerk,
validators::{jwks::MemoryCacheJwksProvider, poem::ClerkPoemMiddleware},
ClerkConfiguration,
};
use poem::{get, handler, listener::TcpListener, web::Path, EndpointExt, Route, Server};
#[handler]
fn hello(Path(name): Path<String>) -> String {
format!("hello: {}", name)
}
#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
let clerk = Clerk::new(ClerkConfiguration::new(
None,
None,
Some("sk_test_F9HM5l3WMTDMdBB0ygcMMAiL37QA6BvXYV1v18Noit".to_owned()),
None,
));
let clerk_poem_middleware = ClerkPoemMiddleware::new(
MemoryCacheJwksProvider::new(clerk.clone()),
true,
Some(vec!["/some/route/to/exclude".to_owned()]),
);
let app = Route::new()
.at("/hello/:name", get(hello))
.with(clerk_poem_middleware);
Server::new(TcpListener::bind("0.0.0.0:3000"))
.run(app)
.await
}
The JWT can be accessed using Data<&ClerkJwt> (or req.data::<ClerkJwt>()).
Roadmap
Production users