{"id":18286189,"url":"https://github.com/jeremyben/json-server-auth","last_synced_at":"2025-04-04T08:04:34.052Z","repository":{"id":48516022,"uuid":"162050836","full_name":"jeremyben/json-server-auth","owner":"jeremyben","description":"Authentication \u0026 Authorization flow for JSON Server","archived":false,"fork":false,"pushed_at":"2023-07-02T21:03:07.000Z","size":268,"stargazers_count":307,"open_issues_count":12,"forks_count":69,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-04-25T18:02:49.664Z","etag":null,"topics":["authentication","authorization","devtools","json-server","jwt","prototyping"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/json-server-auth","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeremyben.png","metadata":{"files":{"readme":"README.MD","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-16T23:32:59.000Z","updated_at":"2024-06-18T13:41:10.829Z","dependencies_parsed_at":"2024-06-18T13:40:57.136Z","dependency_job_id":"576ada07-9a73-445c-bb3f-346bb2bca0ef","html_url":"https://github.com/jeremyben/json-server-auth","commit_stats":{"total_commits":35,"total_committers":1,"mean_commits":35.0,"dds":0.0,"last_synced_commit":"58c64cf8f0e0ccdaf11fb98c613ac785a528ede3"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyben%2Fjson-server-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyben%2Fjson-server-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyben%2Fjson-server-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyben%2Fjson-server-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeremyben","download_url":"https://codeload.github.com/jeremyben/json-server-auth/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247139383,"owners_count":20890221,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","authorization","devtools","json-server","jwt","prototyping"],"created_at":"2024-11-05T13:19:11.564Z","updated_at":"2025-04-04T08:04:34.031Z","avatar_url":"https://github.com/jeremyben.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🔐 JSON Server Auth\n\nJWT authentication middleware for **[JSON Server](https://github.com/typicode/json-server)**\n\nBecause you also need a fake **authentication \u0026 authorization flow** for your prototyping.\n\n## Getting started\n\nInstall **both** JSON Server and JSON Server Auth :\n\n```bash\n# NPM\nnpm install -D json-server json-server-auth\n\n# Yarn\nyarn add -D json-server json-server-auth\n```\n\nCreate a `db.json` file with a `users` collection :\n\n```json\n{\n  \"users\": []\n}\n```\n\nStart JSON server (with _JSON server Auth_ as middleware) :\n\n```bash\njson-server db.json -m ./node_modules/json-server-auth\n# with json-server installed globally and json-server-auth installed locally\n```\n\n##### 📢 but wait !\n\nAs a convenience, **`json-server-auth`** CLI exposes `json-server` bundled with its middlewares :\n\n```bash\njson-server-auth db.json\n# with json-server-auth installed globally\n```\n\n_It exposes and works the same for all [JSON Server flags](https://github.com/typicode/json-server#cli-usage)._\n\n## Authentication flow 🔑\n\nJSON Server Auth adds a simple [JWT based](https://jwt.io/) authentication flow.\n\n### Register 👥\n\nAny of the following routes registers a new user :\n\n- **`POST /register`**\n- **`POST /signup`**\n- **`POST /users`**\n\n**`email`** and **`password`** are required in the request body :\n\n```http\nPOST /register\n{\n  \"email\": \"olivier@mail.com\",\n  \"password\": \"bestPassw0rd\"\n}\n```\n\nThe password is encrypted by [bcryptjs](https://github.com/dcodeIO/bcrypt.js).\n\nThe response contains the JWT access token (expiration time of 1 hour), and the user data (without the password) :\n\n```http\n201 Created\n{\n  \"accessToken\": \"xxx.xxx.xxx\",\n  \"user\": {\n    \"id\": 1,\n    \"email\": \"olivier@mail.com\"\n  }\n}\n```\n\n###### Other properties\n\nAny other property can be added to the request body without being validated :\n\n```http\nPOST /register\n{\n  \"email\": \"olivier@mail.com\",\n  \"password\": \"bestPassw0rd\",\n  \"firstname\": \"Olivier\",\n  \"lastname\": \"Monge\",\n  \"age\": 32\n}\n```\n\n###### Update\n\nAny update to an existing user (via `PATCH` or `PUT` methods) will go through the same process for `email` and `password`.\n\n### Login 🛂\n\nAny of the following routes logs an existing user in :\n\n- **`POST /login`**\n- **`POST /signin`**\n\n**`email`** and **`password`** are required, of course :\n\n```http\nPOST /login\n{\n  \"email\": \"olivier@mail.com\",\n  \"password\": \"bestPassw0rd\"\n}\n```\n\nThe response contains the JWT access token (expiration time of 1 hour), and the user data (without the password) :\n\n```http\n200 OK\n{\n  \"accessToken\": \"xxx.xxx.xxx\",\n  \"user\": {\n    \"id\": 1,\n    \"email\": \"olivier@mail.com\",\n    \"firstname\": \"Olivier\",\n    \"lastname\": \"Monge\"\n  }\n}\n```\n\n#### JWT payload 📇\n\nThe access token has the following claims :\n\n- **`sub` :** the user `id` (as per the [JWT specs](https://tools.ietf.org/html/rfc7519#section-4.1.2)).\n- **`email` :** the user `email`.\n\n## Authorization flow 🛡️\n\nJSON Server Auth provides generic guards as **route middlewares**.\n\nTo handle common use cases, JSON Server Auth draws inspiration from **Unix filesystem permissions**, especialy the [numeric notation](https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation).\n\n- We add **`4`** for **read** permission.\n- We add **`2`** for **write** permission.\n\n_Of course CRUD is not a filesystem, so we don't add 1 for execute permission._\n\nSimilarly to Unix, we then have three digits to match each user type :\n\n- First digit are the permissions for the **resource owner**.\n- Second digit are the permissions for the **logged-in users**.\n- Third digit are the permissions for the **public users**.\n\nFor example, **`640`** means that only the owner can write the resource, logged-in users can read the resource, and public users cannot access the resource at all.\n\n#### The resource owner 🛀\n\nA user is the owner of a resource if that resource has a **`userId`** property that matches his `id` property. Example:\n\n```js\n// The owner of\n{ id: 8, text: 'blabla', userId: 1 }\n// is\n{ id: 1, email: 'olivier@mail.com' }\n```\n\nPrivate guarded routes will use the JWT `sub` claim (which equals the user `id`) to check if the user actually owns the requested resource, by comparing `sub` with the `userId` property.\n\n_Except for the actual `users` collection, where the JWT `sub` claim must match the `id` property._\n\n### Guarded routes 🚥\n\nGuarded routes exist at the root and can restrict access to any resource you put after them :\n\n|    Route     | Resource permissions                                                                                 |\n| :----------: | :--------------------------------------------------------------------------------------------------- |\n| **`/664/*`** | User must be logged to _write_ the resource. \u003cbr\u003e Everyone can _read_ the resource.                  |\n| **`/660/*`** | User must be logged to _write_ or _read_ the resource.                                               |\n| **`/644/*`** | User must own the resource to _write_ the resource. \u003cbr\u003e Everyone can _read_ the resource.           |\n| **`/640/*`** | User must own the resource to _write_ the resource. \u003cbr\u003e User must be logged to _read_ the resource. |\n| **`/600/*`** | User must own the resource to _write_ or _read_ the resource.                                        |\n| **`/444/*`** | No one can _write_ the resource. \u003cbr\u003e Everyone can _read_ the resource.                              |\n| **`/440/*`** | No one can _write_ the resource. \u003cbr\u003e User must be logged to _read_ the resource.                    |\n| **`/400/*`** | No one can _write_ the resource. \u003cbr\u003e User must own the resource to _read_ the resource.             |\n\n#### Examples\n\n- Public user (not logged-in) does the following requests : \n\n| _Request_                               | _Response_         |\n| :-------------------------------------- | :----------------- |\n| `GET /664/posts`                        | `200 OK`           |\n| `POST /664/posts`\u003cbr\u003e`{text: 'blabla'}` | `401 UNAUTHORIZED` |\n\n- Logged-in user with `id: 1` does the following requests :\n\n| _Request_                                                  | _Response_      |\n| :--------------------------------------------------------- | :-------------- |\n| `GET /600/users/1`\u003cbr\u003e`Authorization: Bearer xxx.xxx.xxx`  | `200 OK`        |\n| `GET /600/users/23`\u003cbr\u003e`Authorization: Bearer xxx.xxx.xxx` | `403 FORBIDDEN` |\n\n### Setup permissions 💡\n\nOf course, you don't want to directly use guarded routes in your requests.\nWe can take advantage of [JSON Server custom routes feature](https://github.com/typicode/json-server#add-custom-routes) to setup resource permissions ahead.\n\nCreate a `routes.json` file :\n\n```json\n{\n  \"/users*\": \"/600/users$1\",\n  \"/messages*\": \"/640/messages$1\"\n}\n```\n\nThen :\n\n```bash\njson-server db.json -m ./node_modules/json-server-auth -r routes.json\n# with json-server installed globally and json-server-auth installed locally\n```\n\n##### 📢 but wait !\n\nAs a convenience, **`json-server-auth`** CLI allows you to define permissions in a more succinct way :\n\n```json\n{\n  \"users\": 600,\n  \"messages\": 640\n}\n```\n\nThen :\n\n```bash\njson-server-auth db.json -r routes.json\n# with json-server-auth installed globally\n```\n\nYou can still add any other _normal_ custom routes :\n\n```json\n{\n  \"users\": 600,\n  \"messages\": 640,\n  \"/posts/:category\": \"/posts?category=:category\"\n}\n```\n\n## Module usage 🔩\n\nIf you go the programmatic way and [use JSON Server as a module](https://github.com/typicode/json-server#module), there is an extra step to properly integrate JSON Server Auth :\n\n⚠️ You must bind the router property `db` to the created app, like the [JSON Server CLI does](https://github.com/typicode/json-server/blob/master/src/cli/run.js#L74), and you must apply the middlewares in a specific order.\n\n```js\nconst jsonServer = require('json-server')\nconst auth = require('json-server-auth')\n\nconst app = jsonServer.create()\nconst router = jsonServer.router('db.json')\n\n// /!\\ Bind the router db to the app\napp.db = router.db\n\n// You must apply the auth middleware before the router\napp.use(auth)\napp.use(router)\napp.listen(3000)\n```\n\n#### Permisssions Rewriter\n\nThe custom rewriter is accessible via a subproperty :\n\n```js\nconst auth = require('json-server-auth')\n\nconst rules = auth.rewriter({\n  // Permission rules\n  users: 600,\n  messages: 640,\n  // Other rules\n  '/posts/:category': '/posts?category=:category',\n})\n\n// You must apply the middlewares in the following order\napp.use(rules)\napp.use(auth)\napp.use(router)\n```\n\n## TODO 📜\n\n- [ ] Use JSON Server `id` and `foreignKeySuffix` parameters\n- [ ] Handle query params in list requests to secure guarded routes more precisely\n- [ ] Allow configuration of :\n  - [ ] Users collection name\n  - [ ] Minimum password length\n  - [ ] JWT expiry time\n  - [ ] JWT property name in response\n- [ ] Implement JWT Refresh Token\n- [ ] Possibility to disable password encryption ?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremyben%2Fjson-server-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeremyben%2Fjson-server-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremyben%2Fjson-server-auth/lists"}