Although it is often used for a “Sign in with …” authentication flow, the OAuth protocol actually stands for “Open Authorization”.
It is originally made to authorize access to an API, and has been later “abused” to perform authentication thanks to the OpenID protocol built on top.
In its core, the OAuth protocol works as follow:
- some app or website requests permission to use some parts of the API (the
scope) on behalf of the user.
- once the access
tokenis obtained, it can be used as authorization to access the granted parts of the API.
For example, the scope might be
files calendar mails to grant access to endpoints of the API related to these three scopes.
Now, how exactly you obtain this “access”
token depends on the “flow” you choose. You can request it directly in the browser, which is called “implicit flow”. This is typically used by pure front-end apps without server-side part. Alternatively, you may choose the “authorization code flow”. This basically sends a
code (for the back-end) that can be used only once to obtain the access
token. This is often preferred because it never exposes the access
token to the browser, therefore better from a security perspective.
token, there are no rules regarding its structure. It might be a random ID, also called opaque token, or it might be a Json Web Token (JWT).
OpenID Connect is yet another protocol. It builds upon OAuth 2 in order to provided standardized scopes, API endpoints and content regarding user information.
So basically, a OAuth2/OpenID login works as follow:
- I want to sign in
- Redirect to
https://<id-provider>/authorization?...&scope=openid%20emailto request the authorization for my app to call the API
- At some point you get called back
https://<my-fancy-app>/callback?code=abcd...with the “code”
- Server-side, fetch the access
tokenthanks to the code by calling
- You know have the access
tokento call the
Authorization: Bearer <my-access-tokenand you will lastly obtain the user information, containing the
- Show some welcome message and you are done
The OpenID protocol defines among others:
- default scopes (
- a way to discover
When you think about it, using an “authorization” protocol to fetch a code to fetch a token to fetch a userinfo endpoint is kind of overkill. That is why Passwordless.ID takes some shortcuts to be much simpler and yet stay compatible with OAuth2 / OpenID.
Some simplifications can be made because internet standards evolved since the inception of OAuth2, that it is a public API and that the sole purpose of the API is to deliver OpenID related information.
This leads to the following simple usage:
/openid/authorizationcan be done by anyone by simply using the “origin” as
/openid/userinfoin the browser works out of the box, an access token is already present in a cookie
/openid/tokenin the browser works out of the box, an access token is already present in a cookie
- using the “authorization code” flow where the server receives a code and fetches an access token is still possible too
Obtaining an identity token is therefore trivial, either from the browser using a direct call or from a server by reusing generic OAuth2 / OpenID libraries.
The “access” token itself has no real use regarding Passwordless.ID, since after all the single and only usage of the API is to retrieve the ID token. Nevertheless, it is still possible to retrieve for compatibility purposes with the OAuth2 / OpenID protocol.
Opening up a world of possibilities
The ID token identifies the user. It has two important components:
“sub”: “…” // The user’s ID “aud”: “…” // For which app/website the token was issued for