SETUP GUIDES · SIGN-IN

Sign-in with Claspine in a Spring Boot app

Email and password, Google, phone codes: Claspine checks the sign-in, keeps the sessions and hands your controllers the signed-in person.

⏱ About 20 minutes

In a Spring Boot app with self-hosted Claspine, sign-in is built in. Your login screen talks to a sign-in provider (Firebase Authentication, or Claspine’s own one-time codes). Your app sends the result to Claspine once; Claspine checks it and returns a session. From then on every request carries the session token and your controllers simply ask for the signed-in person. You write no login filter, session table or password code. Claspine Atlas does not sign in your users (see what runs where); on Atlas, keep your own login.

Words you’ll see

Sign-in provider
The service that checks who a person is: Firebase Authentication (email and password, Google, Apple, phone), or Claspine’s own one-time codes sent by SMS, WhatsApp or email. Claspine trusts its answer and opens a session.
ID token
A short-lived signed message from the sign-in provider that says “this is user X”. Your app gets it after the person signs in and hands it to Claspine once, in exchange for a session.
Session
What keeps a person signed in. Claspine gives your app a session token after sign-in; every later request carries it. Claspine checks it, ends it at sign-out, and can end every session of a person at once.

Before you start

  • A Spring Boot 3.5 app with self-hosted Claspine (see Install self-hosted Claspine).
  • For email/password or Google: a free Firebase project (console.firebase.google.com). For codes by SMS, WhatsApp or email: your own message provider (Amazon SNS or Twilio, AWS WhatsApp, Amazon SES or SMTP).

Steps

  1. In Firebase, open Authentication → Get started and switch on the methods you want (Email/Password, Google, Apple, Phone). Under Settings → Authorized domains add the domains your login page runs on.
  2. Tell Claspine which Firebase project to trust: add platform.bootstrap.identity-providers.firebase-project-id to application.yml (snippet below). Claspine stores only the project ID; no service-account file is needed.
  3. On your login page, sign the person in with the Firebase web or mobile SDK (for example signInWithEmailAndPassword or signInWithPopup(new GoogleAuthProvider())) and get the ID token with user.getIdToken().
  4. Exchange it for a session: POST /api/v1/auth/sessions with {"provider":"firebase-auth","credential":"<ID token>","transport":"COOKIE"}. With COOKIE Claspine sets an httpOnly cookie (best for web; send the header X-Requested-With: fetch on POST, PUT and DELETE); with BEARER it returns sessionToken for mobile apps, which send it as Authorization: Bearer ….
  5. In your controllers, add an AuthenticatedPrincipal principal parameter. Signed-out callers get 401 automatically; use Optional<AuthenticatedPrincipal> for pages anyone may open. principal.accountId() is the person’s stable Claspine account ID: store your own profile data against it.
  6. Show who is signed in with GET /api/v1/auth/me; sign out with DELETE /api/v1/auth/sessions/current (or every device with DELETE /api/v1/auth/sessions).
  7. Optional, codes instead of passwords: enable phone-code and/or email-code (snippet). Your page calls POST /api/v1/auth/codes with the number or address, then POST /api/v1/auth/sessions with "provider":"phone-code" and "credential":"<challengeId>:<code>". Claspine sends, checks and rate-limits the codes through your own message provider.
application.yml: sign-in settings. Claspine sets them up at the first start; later starts add new providers.
platform:
  bootstrap:
    enabled: true
    environment: PRODUCTION            # DEVELOPMENT locally
    hosts: [app.example.com]           # where your users reach the app
    identity-providers:
      firebase-project-id: my-firebase-project   # email/password, Google, Apple, phone via Firebase
      # phone-code: { enabled: true, registration: OPEN }            # codes by SMS / WhatsApp
      # email-code: { enabled: true, registration: EXISTING_ONLY }   # codes by email, known people only
      # sandbox: true                  # local testing only; refused in STAGING/PRODUCTION

// A controller: only signed-in people reach it
@GetMapping("/api/notes")
List<Note> notes(AuthenticatedPrincipal principal) {
    return notes.ownedBy(principal.accountId());
}

What goes where in Claspine

Console fieldValue
firebase-project-idFirebase console → Project settings → General → Project ID (not the project name, not the API key).
Firebase web config (your login page)Project settings → General → Your apps → Web app: apiKey, authDomain, projectId, appId. These are public by design; they belong in your frontend, not in Claspine.
registration (codes)<code>OPEN</code>: anyone who proves the number or address gets an account. <code>EXISTING_ONLY</code>: only people your app already added (staff, invited users).

Keep it safe

  • Never write your own session table or login filter next to Claspine’s: one source of truth keeps sign-out and account suspension reliable.
  • Use COOKIE transport for browsers so scripts on the page cannot read the session token.
  • The sandbox provider proves nothing (anyone can claim any user). Claspine refuses it outside DEVELOPMENT and TEST; keep it out of real deployments.
  • Suspending or closing a Claspine account ends all of its sessions at once.

Claspine stores the values encrypted, never shows them again in full, and never sends them to your app or SDK.

If something goes wrong

POST /api/v1/auth/sessions answers 401.
The ID token is from another Firebase project, expired (it lasts one hour; call getIdToken() again), or the provider is not set up for this host. Check firebase-project-id and that the request goes to one of your hosts.
Google sign-in says the domain is not authorized.
Add the login page’s domain in Firebase → Authentication → Settings → Authorized domains.
Controllers answer 401 after sign-in.
Web: send requests from the same site with credentials (fetch(..., { credentials: 'include' })), and add the header X-Requested-With to POST, PUT and DELETE: Claspine ignores the cookie on changes without it, which blocks cross-site request forgery. Mobile: send Authorization: Bearer with the sessionToken.
Codes never arrive.
Turn on your SMS, WhatsApp or email provider as in Notifications in self-hosted Claspine (/docs/notifications-self-hosted/); Amazon SNS sandbox numbers must be verified first. The API always answers 202 so it does not reveal who has an account; check the app log.

← All setup guides