A simple REST API boilerplate created using Hapi, Boom, Joiful, Prisma, Pagination, Swagger and OAuth2.
Warning: for production ready environments change this part as you prefer. This is a simple example, setup of a strong OAuth2 authorization server and advanced configurations are out of the scope of this guide
Prepare your development environment:
$ cp .env.dev .env
Or prepare your production environment:
$ cp .env.prod .env
Generate OAuth2 server secret:
$ export LC_CTYPE=C; cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1
Save secret it in .env*
.
Store OAUTH_SECRET otherwise you will lose access to authorization server
Start all docker-compose services with:
$ docker-compose up -d
Remember to stop all services when finished with:
$ docker-compose down
Create your first OAuth client:
$ docker exec hydra \
hydra clients create \
--endpoint http://127.0.0.1:4445/ \
--id <client-id> \
--secret <client-secret> \
--grant-types authorization_code,refresh_token \
--response-types token,code \
--callbacks http://localhost:3000/api/oauth/authorize
Replace
<client-id>
and<client-secret>
with your custom values
Deploy a sample Login & Consent OAuth App:
$ docker run -d \
--name hydra-consent \
-p 9020:3000 \
--network hydranet \
-e HYDRA_ADMIN_URL=http://hydra-server:4445 \
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
oryd/hydra-login-consent-node:v1.3.2
Initialize database using Prisma migrations:
$ npx prisma migrate dev --name init
Create first user in database:
$ npm run seed
Execute a Prisma migration in development environment:
$ npx prisma migrate dev --name init
Execute a Prisma migration in production environment:
$ npx prisma migrate deploy
Generate Prisma client (after some changes to Prisma model file):
$ npx prisma generate
To introspect database use Prisma Studio:
$ npx prisma studio
REST API endpoint:
http://localhost:3000/api
Swagger endpoint:
http://localhost:3000/api-docs
Follow these steps to complete the setup
-
Use commands before to prepare the environment
-
Go to swagger endpoint:
http://localhost:3000/api-docs#/
- Use default credentials:
Username: admin
Password: admin
-
Make a
GET
request to/api/oauth/authenticate
-
Copy the
authUrl
in the response body and open it in a new browser window -
Login to sample app with credentials
foo@bar.com
as email,foobar
as password and give consent -
After authentication completed, copy the JWT token provided and use it to authorize REST API requests as JWT Bearer token
In order to prevent access token expiration issues an access token lifecycle has been implemented to refresh it when it expires.
If this situation occurs the current request is authorized anyways but starting from next one you should provide newly generated access token, coming back in the Authorization
header of the current response.
This allows full transparency of access token expiration and refresh using the API
Feel free to submit issues and pull requests if you want 😄
- Write tests
- Checks other TODOs in code