How to add authentication to your app using this identity service.
This service implements the OAuth 2.0 Authorization Code Flow with OpenID Connect (OIDC) on top. Your app redirects users to a hosted login page, receives an authorization code, exchanges it for tokens, and then calls the userinfo endpoint to get the authenticated user's profile.
1. User clicks "Login" in your app
2. Redirect to: https://auth.svc.jxs.se/login/{appSlug}?redirect_uri=...&client_id=...&state=...
3. User logs in / registers
4. Auth service redirects to: your redirect_uri?code=xxx&state=xxx
5. Your server POSTs to: https://auth.svc.jxs.se/api/auth/token
6. You receive access_token + id_token
7. Call https://auth.svc.jxs.se/api/auth/userinfo to get user profilehttps://yourapp.example.com/auth/callback)Redirect the user to the login page with these query parameters:
const state = crypto.randomUUID()
// Store state in session cookie to prevent CSRF
const params = new URLSearchParams({
client_id: 'your-client-id',
redirect_uri: 'https://yourapp.com/auth/callback',
state,
response_type: 'code',
scope: 'openid profile email',
})
// Redirect user to:
// https://auth.svc.jxs.se/login/{appSlug}?{params}Replace {appSlug} with your application's slug from the admin panel.
Your redirect URI receives ?code=xxx&state=xxx. Verify the state, then exchange the code for tokens on your server:
// Node.js / Next.js server-side example
const response = await fetch('https://auth.svc.jxs.se/api/auth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'authorization_code',
code: searchParams.get('code'),
redirect_uri: 'https://yourapp.com/auth/callback',
client_id: process.env.AUTH_CLIENT_ID,
client_secret: process.env.AUTH_CLIENT_SECRET,
}),
})
const { access_token, id_token } = await response.json()Use the access token to fetch the authenticated user's profile:
const profile = await fetch('https://auth.svc.jxs.se/api/auth/userinfo', {
headers: { Authorization: `Bearer ${access_token}` },
}).then(r => r.json())
// profile = {
// sub: "user-id",
// email: "user@example.com",
// name: "User Name",
// email_verified: true
// }AUTH_SERVICE_URL=https://auth.svc.jxs.se AUTH_CLIENT_ID=your-client-id # from admin panel AUTH_CLIENT_SECRET=your-secret # from admin panel AUTH_REDIRECT_URI=https://yourapp.com/auth/callback AUTH_APP_SLUG=your-app-slug # your app's slug
/login/{appSlug}Hosted login page for your application. Accepts redirect_uri, client_id, state, scope.
/api/auth/app-registerRegister a new user and get an authorization code. Body: { email, password, name, applicationId, redirect_uri }
/api/auth/tokenExchange authorization code for access_token + id_token. Body: { grant_type, code, redirect_uri, client_id, client_secret }
/api/auth/userinfoGet authenticated user profile. Requires Authorization: Bearer {access_token}
/.well-known/openid-configurationOIDC discovery document with all endpoint URLs.
A live demo app is deployed at testapp.app.jxs.se — it has a login button, secure dashboard, and logout. The source is at ~/workspace/test-app/.