Being able to login is great. But controlling access at a more granular level is vital to creating a scalable system. In this lab, you will implement Role Based Access Control (RBAC) using an Access Control List (ACL), allowing to not only restrict access to routes for valid users, but also based on the individual permissions we give each user.
Over the course of the previous 2 modules, you have separately created an auth-server
and an api-server
... In this lab, you will be integrating those 2 servers to create a single, authenticated API server.
In this final phase, the new requirement is to extend the restrictive capabilities of our routes to our API, implementing a fully functional, authenticated and authorized API Server using the latest coding techniques
Specifically, we want to make the following restrictions:
- Regular users can READ
- Writers can READ and CREATE
- Editors can READ, CREATE, and UPDATE
- Administrators can READ, CREATE, UPDATE, and DELETE
Routes that end up performing those actions in our API/Database need to be protected by both a valid user and that user's permissions
Begin with the 2 servers provided to you in the starter-code
folder.
api-server
is a fully functional API server that performs CRUD operations via RESTauth-server
is a fully functional Auth server, capable of adding users, logging users in, and providing middleware that can be used to protect any route
- Your server should respond to the following routes:
- POST
/signup
to create a user - POST
/signin
to login a user and receive a token - GET
/secret
should require a valid bearer token - GET
/users
should require a valid token and "delete" permissions
- POST
NOTE: You will have some duplicated files and functionality between the 2 servers. Eliminate the waste and end with a single running server with all current routes functional
Restrict access without a valid token AND a specific capability.
- Create a new set of routes (V2) within the server
- V2 API Routes (
/api/v2/...
) must now be protected with the proper permissions based on user capability, using Bearer Authentication and an ACLapp.get(...)
should require authentication only, no specific rolesapp.post(...)
should require both a bearer token and thecreate
capabilityapp.put(...)
should require both a bearer token and theupdate
capabilityapp.patch(...)
should require both a bearer token and theupdate
capabilityapp.delete(...)
should require both a bearer token and thedelete
capability
- V2 API Routes (
- Full Test Coverage
- Well executed UML and WRRC Diagrams
- Polished and Complete Developer Friendly README.md at the root of your repo
The provided server works to support the above requirements, but it has a few principle shortcomings that you must address
- Convert any method that's using promise syntax (
.then()
) to use the more modernasync
/await
syntax - Ensure that all route handler methods, middleware methods, model methods are properly catching and responding to errors.
- Do you have
try/catch
in place wherever you can? - Are you logging full errors to the console?
- Are you giving properly formatted errors to the browser in the response?
- Do you have
- Write a suite of tests that make the following assertions, at minimum:
- AUTH Routes
- POST /signup creates a new user and sends an object with the user and the token to the client
- POST /signin with basic authentication headers logs in a user and sends an object with the user and the token to the client
- V1 (Unauthenticated API) routes
- POST /api/v1/:model adds an item to the DB and returns an object with the added item
- GET /api/v1/:model returns a list of :model items
- GET /api/v1/:model/ID returns a single item by ID
- PUT /api/v1/:model/ID returns a single, updated item by ID
- DELETE /api/v1/:model/ID returns an empty object. Subsequent GET for the same ID should result in nothing found
- V2 (Authenticated API Routes)
- POST /api/v2/:model with a bearer token that has
create
permissions adds an item to the DB and returns an object with the added item - GET /api/v2/:model with a bearer token that has
read
permissions returns a list of :model items - GET /api/v2/:model/ID with a bearer token that has
read
permissions returns a single item by ID - PUT /api/v2/:model/ID with a bearer token that has
update
permissions returns a single, updated item by ID - DELETE /api/v2/:model/ID with a bearer token that has
delete
permissions returns an empty object. Subsequent GET for the same ID should result in nothing found
- POST /api/v2/:model with a bearer token that has
- AUTH Routes
We have deployed a web application that's designed to test your Server. This is a good way to ensure that your system works as expected. There's nothing to "turn in" here, this is provided for your benefit.
- Open this Web Application
- Click the "Module 3 (AUTH) / ACL" Link
- In the form at the top of the page, enter the URL to your Authentication Server and all other relevant information
- First login with a username and password
- Then, you should see buttons that would invoke each of the routes described above.
- Based on your role, each button will give you a good or a bad response.
-
/signup
- Used to create a new user with a password
-
/signin
- Used to sign in with a user and password
-
/users
- Used to show all users
-
/secret
- Used to open a secret page
-
/api/v1/food
-
/api/v1/clothes
-
/api/v2/food
-
/api/v2/clothes
- AUTH Routes
- POST /signup creates a new user and sends an object with the user and the token to the client
- POST /signin with basic authentication headers logs in a user and sends an object with the user and the token to the client
- V1 (Unauthenticated API) routes
- POST /api/v1/:model adds an item to the DB and returns an object with the added item
- GET /api/v1/:model returns a list of :model items
- GET /api/v1/:model/ID returns a single item by ID
- PUT /api/v1/:model/ID returns a single, updated item by ID
- DELETE /api/v1/:model/ID returns an empty object. Subsequent GET for the same ID should result in nothing found
- V2 (Authenticated API Routes)
- POST /api/v2/:model with a bearer token that has
create
permissions adds an item to the DB and returns an object with the added item - GET /api/v2/:model with a bearer token that has
read
permissions returns a list of :model items - GET /api/v2/:model/ID with a bearer token that has
read
permissions returns a single item by ID - PUT /api/v2/:model/ID with a bearer token that has
update
permissions returns a single, updated item by ID - DELETE /api/v2/:model/ID with a bearer token that has
delete
permissions returns an empty object. Subsequent GET for the same ID should result in nothing found
- POST /api/v2/:model with a bearer token that has
-
- For the repo auth-api clicks => here.
- Pull Requests:
- Local Tests:
- GitHub Tests:
-
-
/signup
Return JSON objects{ "user": { "_id": "60ad21b46ee66807acaacf6e", "username": "shady66", "password": "$2b$10$9Aa9KXApHALFsDz/HfBSYedqF.udhW8CMwZH64iPjghJKCJR8kxUK", "__v": 0 }, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InNoYWR5NjYiLCJpYXQiOjE2MjE5NTkxNzMsImV4cCI6MTYyMjg1OTE3MywiaXNzIjoic2hhZHkiLCJqdGkiOiJqd3RpZCJ9.o7oRaqVoD14aHaZlBD15o61-NRRi-btYvdclRwzSsZg" }
-
/signin
Return JSON objects{ "user": { "_id": "60ad21b46ee66807acaacf6e", "username": "shady66", "password": "$2b$10$9Aa9KXApHALFsDz/HfBSYedqF.udhW8CMwZH64iPjghJKCJR8kxUK", "__v": 0 }, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InNoYWR5NjYiLCJpYXQiOjE2MjE5NTkxNzMsImV4cCI6MTYyMjg1OTE3MywiaXNzIjoic2hhZHkiLCJqdGkiOiJqd3RpZCJ9.o7oRaqVoD14aHaZlBD15o61-NRRi-btYvdclRwzSsZg" }
-
/secret
Return a custom sentenceWelcome to the secret area!
-
-
[ "shady9v", "shady66" ]
-
-
-
- run
npm test
- Auth Middleware ➡️ bearer-auth-middleware.test.js
- Auth Router ➡️ router.test.js
- Auth Middleware ➡️ basic-auth-middleware.test.js
- api v1 ➡️ v1.test.js
- api v2 ➡️ v2.test.js
- run
-
- run
npm start
ornodmon
- visit Herokue depolyed app here
- run
-
I did this lab with help of
- dependencies
- morgen
- mongoose
- cors
- express
- dotenv
- bcrypt
- base-64
- jsonwebtoken
- devDependencies
- supertest
- jest
- eslint
- supergoose
- framework
- Node.js
- tools
- Github.
- Heroku.
- VsCode.
- Ubuntu.
- atlas mongodb
- Postman
- dependencies