Authorize
The page you send somebody to. They sign in, see what you ask for, and come back to your redirect address with a one-time code.
Sign in to see your own test client ID in the samples.
GET https://accounts.aton-network.org/oauth/authorize
When to use it
Every time somebody chooses Sign in with Atheron in your app. Build the address on your server, keep the verifier, state and nonce for this browser, then redirect.
Authentication
None: it identifies your app by client_id and proves the request is yours with PKCE.
Parameters
| Name | In | Type | Required | Limits | What it is |
|---|---|---|---|---|---|
response_type | query | string | yes | code | Always code. The implicit and hybrid flows are not offered. |
client_id | query | string | yes | test-<16 hex> or live-<16 hex> | Your test or live client ID, from the app's Sign-in page. |
redirect_uri | query | string | yes | one registered address, matched exactly, up to 500 characters | Where we send the person back. No wildcards and no prefixes: the whole address must equal one you registered. |
scope | query | string | yes | space separated; openid is added if missing | What you ask for. Every scope is shown on the consent screen. See Scopes and claims. |
code_challenge | query | string | yes | 43 to 128 characters, base64url | BASE64URL(SHA-256(code_verifier)). Required of every client, including server apps that hold a secret. |
code_challenge_method | query | string | yes | S256 | plain is refused. |
state | query | string | no | up to 500 characters | Returned unchanged. Make it random per sign-in, keep it, and compare it in constant time when the person comes back. |
nonce | query | string | no | up to 500 characters | Copied into the ID token. Check it there to stop a token being replayed into another sign-in. |
prompt | query | string | no | none, login, consent or create | none: answer at once or send an error. login: ask them to sign in again. consent: show the consent screen even if they agreed before. create: open registration. |
max_age | query | integer | no | whole seconds, 0 or more | The oldest sign-in you accept. Older, and they sign in again. |
login_hint | query | string | no | an email address | With prompt=create, starts registration with this address filled in. |
Request
# The authorize request is a page the person opens, not an API call. Build the address on your
# server: a fresh PKCE pair, state and nonce for this browser, then redirect them to it.
VERIFIER=$(openssl rand -base64 32 | tr '+/' '-_' | tr -d '=\n')
CHALLENGE=$(printf '%s' "$VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr '+/' '-_' | tr -d '=\n')
STATE=$(openssl rand -hex 16)
echo "https://accounts.aton-network.org/oauth/authorize?response_type=code&client_id=$ATHERON_CLIENT_ID&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&scope=openid%20profile%20email&state=$STATE&code_challenge=$CHALLENGE&code_challenge_method=S256"Response
http
HTTP 302
location: https://app.example.com/callback?code=Qx7...&state=af0ifjsldkj
(no body: the browser follows the redirect)Errors
| HTTP | error | Cause | Fix |
|---|---|---|---|
| on the redirect | access_denied | The person chose not now, or your app may not sign them in yet: a test app signs in only its team and named testers, a live app only after review, and nothing while it is suspended. | Show a way to try again. Read error_description to tell the cases apart, and add testers on the app's Testers page. |
| 400 | invalid_request | A parameter is missing or malformed: no PKCE, PKCE with plain, a bad max_age, prompt=none combined with another prompt, or a token request that is not form encoded. | Send every required parameter once, PKCE with S256, and form-encode the token request. |
| on the redirect | invalid_scope | A scope does not exist, or your client is not registered for it. | Add the scope on the app's Sign-in page. A sensitive scope on the live app needs a review first. |
| on the redirect | unsupported_response_type | response_type is not code. | Use the authorization code flow. |
| on the redirect | login_required | prompt=none was sent and nobody is signed in, or their sign-in is older than max_age. | Send them again without prompt=none. |
| on the redirect | consent_required | prompt=none was sent and the person has not agreed to these scopes yet. | Send them again without prompt=none. |
| on the redirect | interaction_required | prompt=none was sent and their account needs a step first, such as accepting new terms. | Send them again without prompt=none. |
Good to know
- A parameter that decides where the code goes (client_id, redirect_uri, scope, response_type, code_challenge and the like) may appear once. Repeating one stops the request.
- An unknown client, an unregistered redirect address and a repeated parameter are shown on our page and never sent back: we never send anybody to an address we have not checked.
- A test client signs in only its team and up to 25 testers who accepted an invitation. Anybody else comes back with access_denied.
- The code lasts 60 seconds and works once.
Security
- Always send state and check it. Without it, somebody can sign a victim in to the attacker's account.
- Build the address on your server. Never let the browser choose the redirect_uri or the scopes.
Ask Atlas
AI assistantAsk anything about Sign in with Atheron, the API or the portal. You get an answer from our docs, with links to the pages it used.