What the MangaBaka OAuth provider supports, how long its tokens live, and the behaviour most likely to trip up a client.
For a walkthrough, see Let users sign in with OAuth. The machine-readable version is the discovery document.
Read this first#↑
- Always request
openid. The API checks every bearer token against the userinfo endpoint, which requiresopenid. A token without it gets401on every endpoint, whatever other scopes it has. - PKCE is required for every client, Web apps with a secret included. Only
S256. - Store the new refresh token on every refresh. Sending a retired one revokes every token your app holds for that user.
redirect_urimust match exactly, in the authorize request and again in the token request. An extra/or query string is rejected.- OAuth tokens go in
Authorization: Bearer. Personal access tokens go inx-api-key. Swapping them gets401, and sending both gets400. - Client credentials tokens don't work with the API. They have no user, and the API needs one.
Endpoints#↑
All under https://mangabaka.org. Issuer: https://mangabaka.org/auth.
| Endpoint | URL |
|---|---|
| Authorize | /auth/oauth2/authorize |
| Token | /auth/oauth2/token |
| Userinfo | /auth/oauth2/userinfo |
| Revoke | /auth/oauth2/revoke |
| Introspect | /auth/oauth2/introspect |
| Signing keys | /auth/jwks |
The API itself is on https://api.mangabaka.org.
What's supported#↑
| Feature | Supported |
|---|---|
| Grant types | authorization_code, refresh_token |
| Response type and mode | code, returned in the query string |
| PKCE | S256, required |
| Client authentication | Web apps: client_secret_basic or client_secret_post. Public apps: client_id only |
prompt |
login, consent, none |
| Access tokens | Opaque strings. Not JWTs, so don't try to decode them |
| ID tokens | JWT signed with EdDSA, keys at /auth/jwks |
| Scopes | See OAuth scopes |
Token lifetimes#↑
| Token | Lifetime |
|---|---|
| Authorization code | 10 minutes |
| Access token | 7 days |
Access token that includes mod |
1 day |
| Refresh token | 365 days, counted again from each refresh |
| ID token | 10 hours |
expires_in in the token response is the access token's lifetime in seconds.
Refresh tokens#↑
- You only get one if you ask for
offline_access. - Each refresh returns a new refresh token and retires the old one.
- You can ask for fewer scopes on refresh by sending
scope, never more. Dropoffline_accessand the next response has no refresh token.
Consent#↑
- A user who has approved your app isn't asked again while you request the same scopes or fewer.
- Approving a new set of scopes replaces the old set, it doesn't add to it. Request everything you need in one go.
- Users approve all requested scopes or none.
prompt=nonereturnslogin_requiredorconsent_requiredto yourredirect_uriinstead of showing a page.
Redirects#↑
- Success:
code,stateandissin the query. Check thatissishttps://mangabaka.org/auth. - Errors:
error,error_description,stateandiss. A user who declines getsaccess_denied. - If the
client_idorredirect_uriis wrong, the user lands on a MangaBaka error page instead, since there is no safe place to send them. - Plain
httpredirect URLs are only accepted forlocalhost,127.0.0.1and[::1]. - For
127.0.0.1and[::1], any port matches the registered URL, so a native app can pick a free port at runtime.localhostmust match the port exactly.
User identity#↑
Call the userinfo endpoint with the access token. It returns:
sub: the user's id. This is theuser_idother endpoints use.preferred_username,nickname,nameandpicture.badges, with thebadgesscope.
There is no email. The ID token carries little beyond sub, so use userinfo for profile data.
Revoking and inspecting tokens#↑
- Revoke takes
token,token_type_hint(access_tokenorrefresh_token) andclient_id, plus the secret for Web apps. - Introspect needs the client secret, so it only works for Web apps, and only for tokens issued to that app.
Not available#↑
- Dynamic client registration. Register apps under New application.
- The end-session (logout) endpoint. Revoke the refresh token instead.
- Resource indicators (
resource). The token endpoint answers400 invalid_target.