JWT Auth using Access Token and Refresh Token
Framework: Nestjs
Db: MongoDB
# installs npm packages
$ npm i
# for running local mongodb server
$ docker-compose up -d
# or
# to give existing mongodb credentials, add them in .env file
Script for creating dummy users
# for loading dummy users into db
$ npx ts-node ./src/scripts/load_initial_users.ts
These are the usernames & passwords created using this script.
username | password |
---|---|
vinod | password@123 |
sai | password@123 |
sreenivas | password@123 |
# development with watch
$ npm run start:dev
# development
$ npm run start
http://localhost:3000/docs/auth
Note: Change access token secret and refresh token secret present in config folder. Encrypt config files before pushing to git
# prod
$ npm run build
$ npm run start:prod
GET /docs/auth
API to create an access token along with a refresh token for each user. Access token validity is 1 hr and refresh token validity is 1 year.
POST /api/auth/login
Body
{
"password": "string",
"username": "string"
}
Response
{
"access_token": "ACCESS_TOKEN_JWT",
"access_token_expires_in": "1h",
"refresh_token": "REFRESH_TOKEN_JWT",
"refresh_token_expires_in": "1y"
}
API to validate incoming request and check token validity.
GET /api/auth/validate
Authorization: Bearer ACCESS_TOKEN
Response
{
"username": "USERNAME",
"userId": "USER_ID"
}
To validate a incoming request, we have to use this decorator for that action.
@UseGuards(JwtAccessAuthGuard)
API to refresh the token in case of the access token is expired using refresh token provided with access token creation
POST /api/auth/refresh
BODY
{
"refresh_token": "REFRESH_TOKEN"
}
Response
{
"access_token": "ACCESS_TOKEN_JWT",
"access_token_expires_in": "1h"
}
API to remove the refresh token from the db. Access token should be removed from the client side.
POST /api/auth/logout
BODY
{
"refresh_token": "REFRESH_TOKEN"
}
Response
{
"message": "success"
}
- Access Token Expiry: 1 hour
- Refresh Token Expiry: 1 year
- On Logout, the refresh tokens is deleted from the db. Access token should be removed from the client side.
- Access Tokens are not maintained in db. On Logout if the access tokens also needs to be invalidated then we have to maintain them also in db.
-
users
-
Columns:
_id
,username
,password
,passwordSalt
,createdAt
,updatedAt
-
indexes:
username
-
-
refreshtokens
-
Columns:
_id
,userId
,refreshToken
,createdAt
,updatedAt
-
indexes
userId
(userId is used to clear all the sessions of the user)refreshToken
(used for clearing only the current session)createdAt
(with 1 year ttl)
-
Note:
-
passwordSalt
is a random string. Different for each user. Every time password is changed, passwordSalt should be changed -
password
stored in db is sha256(actualUserPassword + passwordSalt)
TODO: Unit Tests & E2E Tests