json-data-server

1.0.0 • Public • Published

json-data-server

json-server based data provider with jwt authentication

Highly inspired from json-server-auth by Jemery Bensimon with the following differences:

  • No routing guards, all routes are protected and there is no ownership check (could be added in the future if needed in my projects)
  • Credentials data is separated from the main database (passwords are stored in another file)
  • Everything is configurable (requests content, authorization routes, responses content, etc..), see more below

Get and run

git clone https://gitlab.com/riribreizh/json-data-server.git
npm i

Then create configuration and data files with empty data by default:

npm run initdata

Run it!

npm start

Usage

All authentication routes are valid on POST requests only. Any other method is not considered an authentication action, and follows the normal routing scheme of json-server.

On error, you usually get a 400 (bad request) HTTP code, with the reason in plain text.

HTTP 400
"Invalid password"

Or if you try to access a route without a valid token:

HTTP 401
"No authorization"

Registration

Create user and activates a session on it.

POST /auth/register
{ "id": "username", "password": "clear-pwd", "any": "other data" }
HTTP 200
{ "access_token": "token", "refresh_token": "longer token" }

Login

Authenticate an existing user.

POST /auth/login
{ "id": "username", "password": "clear-pwd" }
HTTP 200
{ "access_token": "token", "refresh_token": "longer token" }

Logout

Not implemented.

Checking token

Checks the validity of an access token, returning the reason if it is not valid.

POST /auth/check
{ "id": "username", "access_token": "token" }
HTTP 200
{ "valid": true }
HTTP 200
{ "valid": false, "reason": "jwt expired" }

Refresh token

Access token lifetime is short (should be). So the refresh token with a longer lifetime (not too much) is used to permit to recreate an access token without requiring the users to enter their password again.

  1. make a request with your access token
  2. if the server replies 401 (unauthorized), send a refresh request with the refresh token
  3. if the refresh token didn't expired, you receive a new pair of access and refresh tokens
  4. make your initial request with the new access token :)
POST /auth/refresh
{ "id": "username", "refresh_token": "token" }
HTTP 200
{ "access_token": "token", "refresh_token": "longer token" }

Change user password

Change user password and send a new pair of access and refresh tokens (new session).

POST /auth/password
{ "id": "username", "password": "clear-pwd", "newpassword": "clear-new-pwd" }
HTTP 200
{ "access_token": "token", "refresh_token": "longer token" }

Configuring

The server uses json-server configuration, but the configuration file is forced to config.json (you can change it in the start script in package.json).

So you can put there all json-server related configurations, like the port:

{
  "port": 4000
}

Authentication configuration is placed in a auth property in this configuration. The following shows all configurable items with their default value if not specified:

{
  "auth": {
    "registerRoute": "/auth/register",
    "loginRoute": "/auth/login",
    "logoutRoute": "/auth/logout",
    "checkRoute": "/auth/check",
    "refreshRoute": "/auth/refresh",
    "passwordRoute": "/auth/password",
    "credentialsFile": "credentials.json",
    "usersProp": "users",
    "userId": "id",
    "reqUserId": "username",
    "reqUserPassword": "password",
    "reqNewPassword": "newpassword",
    "userIdRE": ".*",
    "userPwdRE": ".*",
    "passwordSalt": 10,
    "jwtSecret": "DefaultJWTSecretString-LOL",
    "jwtAccessToken": "access_token",
    "jwtRefreshToken": "refresh_token",
    "jwtExpiresIn": "1m",
    "jwtRefreshExpiresIn": "1d",
    "jwtClockTolerance": 2
  }
}

Authentication Routes

All default authentication action routes are prefixed by /auth. Set the desired routes for various authentication actions, or disable thoses you don't want by setting an empty route:

  • registerRoute - register a new user
  • loginRoute - authenticate an existing user
  • logoutRoute - unimplemented for now (the server does not contain any session state)
  • checkRoute - check the validity of a JWT token
  • refreshRoute - get a new pair of access token and refresh token from a valid refresh token
  • passwordRoute - change user's password

Credentials file

Passwords are not stored in the main database (db.json), and during registration, it is removed from the user creation payload. Passwords are stored in credentials.json, which name can be changed with credentialsFile setting.

The format of this file is simple:

{
  "passwords": [
    {
      "sub": "identity name (see userId)",
      "password": "bcrypt hashed password"
    }
  ]
}

The salt used to hash the passwords can be changed with the passwordSalt setting.

User related things

The accredication relies on the main database, by default on the users resource. But this can be changed with the usersProp setting if that does not go well with your data model.

Similarly, the identifier used to find users is id by default, but can be overriden with the userID setting.

On requests

The authentication does not force your API to adhere to common props in requests. reqUserId, reqUserPassword and reqNewPassword are the field names expected in requests. You can change them to follow your API client's needs.

userIdRE and userPwdRE are regular expressions used to validate fields in requests, so you can easily adapt the validity check to your fields (for example for an email or passwords needs).

About JWT

Tokens are not in rest (sic ^^).

  • jwtSecret is your secret signing key, please change it :)
  • jwtExpiresIn is the expiration delay of the access token, with various ways to specify it
  • jwtRefreshExpiresIn is the same, but for the refresh token
  • jwtClickTolerance is the amount of seconds allowed after the expiration time in validation checks, to overcome time difference between devices
  • jwtAccessToken is the name of the access token field in the responses so that you can use any name for your project
  • jwtRefreshToken is the same for refresh token :)

TODO

  • allow automatic creation of credentials.json if it does not exist
  • watch external changes on credentials.json and config.json to reload settings and data
  • permit to disable the creation of tokens on registration (for example to provide an email confirmation process before getting a valid session)
  • implement session handling on server side and the corresponding logout action
  • handling route guards like json-server-auth

Package Sidebar

Install

npm i json-data-server

Weekly Downloads

1

Version

1.0.0

License

MIT

Unpacked Size

29.3 kB

Total Files

5

Last publish

Collaborators

  • riribreizh