This repository is an object lesson of an OAuth 2.1 protocol integration on a basic Fastify API. I made it for learning purposes, so feel free to contribute ! 🙃
To start, just clone this repository and then use:
yarn install # or using pnpm: pnpm install
Before starting the node server, be sure to have a .env
file matching .env.example
. (I will come back after on the specific values to setup in it)
Then just run the following start command:
yarn dev # or using pnpm: pnpm dev
The auth server is by default listening on port 3000
I won't reinvent the wheel so I suggest you to read the The OAuth 2.0 Authorization Framework from the Internet Engineering Task Force. It's maybe not the most beautiful documentation but it's by far one of the most complete and accurate.
Here's the basic protocol flow:
+--------+ +---------------+
| |--(A)------- Authorization Grant --------->| |
| | | |
| |<-(B)----------- Access Token -------------| |
| | & Refresh Token | |
| | | |
| | +----------+ | |
| |--(C)---- Access Token ---->| | | |
| | | | | |
| |<-(D)- Protected Resource --| Resource | | Authorization |
| Client | | Server | | Server |
| |--(E)---- Access Token ---->| | | |
| | | | | |
| |<-(F)- Invalid Token Error -| | | |
| | +----------+ | |
| | | |
| |--(G)----------- Refresh Token ----------->| |
| | | |
| |<-(H)----------- Access Token -------------| |
+--------+ & Optional Refresh Token +---------------+
OAuth 2.1 is an in-progress effort to consolidate and simplify the most commonly used features of OAuth 2.0. You can go here for more details.
But the main changes are the following:
-
The authorization code grant is extended with the functionality from PKCE (Proof-Key for Code Exchange)
-
Redirect URIs must be compared using exact string matching
-
The Implicit grant (response_type=token) is omitted
-
The Resource Owner Password Credentials grant is omitted
-
Bearer token usage omits the use of bearer tokens in the query string of URIs
-
Refresh tokens for public clients must either be sender-constrained or one-time use
This API provides endpoints to test OAuth flow all by yourself without any front-end. The limit however is that as there is no front-end application you need to do some more steps by yourself in order to make it work. Of course in a production ready application it would'nt have been done this way.
You can register a new user in two ways, first you can use the POST /auth/register
route to register a user by sending an email
For a third party provider, the register process is the same that an authentication.
⚠️ As the 2.1 standard specifies, using the password must be avoided as much as possible
Request POST /auth/authenticate
with the right email and the right password and you will be granted an access/refresh tokens duet.
Request POST /auth/authenticate
with the refresh_token
you stored from your last authentication request and you will be granted a new access/refresh tokens duet.
The authorization code allows you to register using a code provided by a third party solution (like Google or Github). In this example we use the provided code to access you public data on these providers api and then create an access/refresh tokens duet.
ℹ️ You can find the documentation for Google Api using OAuth here
-
Step 1: Request
GET /helpers/pkce
to get yourcode_challenge
and yourcode_verifier
required for the PKCE flow.
⚠️ Don't forget to set your own code_challenge generated earlier in the url
-
Step 3: After connecting with your credentials you will be redirected to the
GET /helpers/callback
with your authorization code. -
Step 4: Request
POST /auth/authenticate
with the rightgrant_type
, thecode
you just received, and also thecode_verifier
and you should get a access/refresh tokens duet as response.
⚠️ It's mandatory to use thecode_verifier
used to encrypt the code_challenge otherwise it cannot work.
ℹ️ As Github does not support PKCE you can ignore
code_verifier
andcode_challenge
-
Step 1: Navigate to this url: https://github.com/login/oauth/authorize?client_id=3f2c99a3de279ba209fb](https://github.com/login/oauth/authorize?client_id=3f2c99a3de279ba209fb) where
client_id
refers to the client_id of the github app I've created for this exemple following this. -
Step 2: After connecting with your credentials you will be redirected to the
GET /helpers/callback
with your authorization code. (this url is set as callback url in github configuration) -
Step 3: Request
POST /auth/authenticate
with the rightgrant_type
and thecode
you just received, and you should get a access/refresh tokens duet as response.
To access restricted data, just set the authorization header as a "Bearer" token corresponding to your refresh_token
You can found the documentation here 👈