Authentication
Astapa handles the entire authentication flow for your end users. Redirect them to our hosted login page, we handle signup, email verification, OAuth, and password resets. You get back a signed JWT with the user's identity and claims.
Supported sign-in methods
1Get your credentials
Create a project in your dashboard. You'll need three things:
| Credential | Where to find it |
|---|---|
client_id | Project settings → General |
client_secret | Project settings → General (shown once) |
redirect_uri | Project settings → Redirect URIs |
client_secret in client-side code. The token exchange must happen on your server.2Redirect to hosted login
Send your users to Astapa's hosted login page. The URL takes two required query parameters: your client_id and the redirect_uri where we'll send them after authentication.
The hosted login page handles everything: signup, login, email verification, password reset, and OAuth. Your users never leave a polished, branded experience.
const loginUrl = "https://astapa.com/auth/login";
const params = new URLSearchParams({
client_id: "your_client_id",
redirect_uri: "https://yourapp.com/callback",
});
// Redirect the user
window.location.href = `${loginUrl}?${params}`;astapa.com. If you're self-hosting, replace with your deployment's origin.3Exchange the authorization code
After the user authenticates, we redirect them to your redirect_uri with a code query parameter. Your backend exchanges this code for tokens:
// In your callback route handler
const code = searchParams.get("code");
const res = await fetch("https://astapa.com/api/platform/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "authorization_code",
code,
client_id: process.env.ASTAPA_CLIENT_ID,
client_secret: process.env.ASTAPA_CLIENT_SECRET,
redirect_uri: "https://yourapp.com/callback",
}),
});
const { access_token, refresh_token, token_type, expires_in } = await res.json();
// Store tokens securely (httpOnly cookies recommended)
// access_token expires in 3600 seconds (1 hour)
// refresh_token is long-lived — use it to get new access tokens4Verify the JWT
The access token is a signed JWT (RS256). Verify it using our JWKS endpoint to get the public key. This ensures the token hasn't been tampered with and was issued by Astapa.
import jwt from "jsonwebtoken";
import jwksClient from "jwks-rsa";
const client = jwksClient({
jwksUri: "https://astapa.com/.well-known/jwks.json",
cache: true,
rateLimit: true,
});
function getKey(header, callback) {
client.getSigningKey(header.kid, (err, key) => {
callback(err, key?.getPublicKey());
});
}
// Verify the token
jwt.verify(access_token, getKey, { algorithms: ["RS256"] }, (err, decoded) => {
// decoded.sub → end user ID
// decoded.email → user email
// decoded.custom_claims.plan → subscription plan
});jwks-rsa) to avoid hitting the endpoint on every request.Refreshing tokens
Access tokens expire after 1 hour. Use the refresh token to get a new access token without asking the user to log in again. This is typically done in your middleware when you detect an expired JWT.
const res = await fetch("https://astapa.com/api/platform/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "refresh_token",
refresh_token: stored_refresh_token,
client_id: process.env.ASTAPA_CLIENT_ID,
client_secret: process.env.ASTAPA_CLIENT_SECRET,
}),
});
const { access_token, refresh_token } = await res.json();
// Both tokens are rotated — store the new refresh_tokenRevoking tokens (logout)
To log a user out completely, revoke their refresh tokens server-side, then clear any cookies or local storage on the client. The user won't be able to refresh their session anymore.
// Revoke all refresh tokens for this user
await fetch("https://astapa.com/api/platform/revoke", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: process.env.ASTAPA_CLIENT_ID,
client_secret: process.env.ASTAPA_CLIENT_SECRET,
email: "user@example.com", // or end_user_id: 42
}),
});
// Then clear cookies on the client sideAPI reference
Complete endpoint documentation for the authentication flow.