Skip to content

The login page

When a realm member has not yet authenticated with your platform, the Oase app opens your login page in a browser (a system browser sheet on iOS/Android, a full redirect on the web):

GET {oidc_authentication_uri}
?client_id={oidc_client_id}
&redirect_uri={redirect_uri}
&response_type=id_token <- sent by the native app flow
  • oidc_authentication_uri and oidc_client_id are the values you supply at registration time (see Registration).
  • On the web app the URL is built manually and carries only client_id and redirect_uri — do not require response_type, scope, state or nonce to be present.
  • The native flow uses an OIDC implicit-style request (response_type=id_token), so standard parameters like state may also be present; echo them back if your framework does, but Oase does not depend on them.

After authenticating the user, your page must redirect to redirect_uri with the token in an id_token (or token) parameter — query or fragment, the app parses both:

{redirect_uri}&id_token={token}

The redirect URIs to allow-list on your side:

Platform Redirect URI
iOS / Android oase://third_party/authenticate?oaseId={realm_id}
Web https://{app-origin}/third_party/authenticate?oaseId={realm_id}&andThen={url}

Note that the redirect URIs contain query parameters (oaseId, andThen): your redirect-URI validation must accept that, and you must append the token parameter to the existing query/fragment rather than replacing it — the app needs both oaseId and id_token present in the final redirect to complete the flow.

Oase publishes its redirect URIs, together with a display name and logo, at a well-known URL:

https://oase.app/.well-known/third-party-identity-provider.json
{
"name": "Oase",
"logo_url": "https://oase.app/favicon.png",
"allowed_redirect_uris": [
"oase://third_party/authenticate",
"https://oase.app/third_party/authenticate",
"http://localhost:3000/third_party/authenticate"
]
}

Rather than hard-coding the table above, your login page can fetch this file and accept a redirect_uri when its scheme, host and path match one of the allowed_redirect_uris entries — compare without the query string, since the query carries the per-request oaseId and andThen. The file is the authoritative list: when Oase adds an origin, it appears here first. Cache it (hours are fine) and fall back to the last good copy if a fetch fails, so a blip on our side never blocks your users’ logins. name and logo_url are there for a “Continue to Oase” style prompt on your side, if you show one. The localhost entries are for development builds of the Oase app and are safe to ignore in production.

Oase treats the token as opaque. It is stored verbatim and replayed as Authorization: Bearer {token} against your SCIM endpoint. In particular, Oase does not:

  • validate a JWT signature, fetch a JWKS, or use OIDC discovery,
  • inspect any claims (sub, aud, exp, …),
  • run a token-exchange (code → token) flow — there is no token endpoint involved and no client secret.

So despite the “OIDC” label, the actual contract is: an implicit-style browser flow that hands the app an opaque bearer token which your own SCIM endpoint will accept. The token can be a JWT, a random session key, whatever — only you ever interpret it.