Node.js check authorization for protected api service/webpage
We have learnt authentication before but it is not enough for some applications. Some application also require to check each user's role in order to allow them to use a particular service. Take a company as scenario, engineer only has the right to submit a purchasing order of electronic components for development and department head has the right to approve/reject the order. Other engineer cannot approve/reject the order. We will implement the authorization in this post.
Below picture is the flow chart. First, the client has to login in order to reach the protected path. Then, the server will check the role of the user and the authorized right of that role. The request is served only if the role has the right to access the service.
Flowchart of checking Authorization
We will use source code(v3.2) in post Node.js use passport authentication in middleware to modify. The final code of this practice is uploaded to github. And we see the explanation of the code below. We rename v3.2_act_as_access_middleware.js to index.js here.
We create a new file respository.js and put all user account, service and role table into it. In real case, those information should be stored in database.
| id | name | password | roleId |
|---|---|---|---|
| 1 | Tom | 123456 | 1 |
| id | name |
|---|---|
| 101 | serviceA |
| 102 | serviceB |
| 103 | serviceC |
| 104 | serviceD |
| roleId | permitServices |
|---|---|
| 1 | 101,102 |
Then we create a new file service.js to implement those services required authorization check. We have created 4 service functions here. Then We may think in intuitive way to add the permission check as the middleware of the route path.
or we invoke a check function before calling the service:
Both ways are workable.
However, we also can bind the permission check and service function together. We can wrap the service function into the permission check function (I had learnt this from a book[1]). Look at the function permissionCheck(), it receives 2 parameters: 1st is the name of service that is going to use and 2nd is the function that is going to execute if the user is authorized.
First, we get the service_id that represent the service. Then we return a function in which the user role and its authorized service are checked. We return function here because we would not execute at this moment. We hope this function will execute when the client request the service at the runtime. We assign the function inside an object as a property and the property name is the same as the service (look at authorizedServices the bottom lines). This function accept (req, res) because we are going to invoke this function inside the body of app.get() route.
In index.js file, we import service and invoke serviceA in GET /api/secreta route. Now, the server will execute the anonymous function returned by permissionCheck() defined in service.js. If the list of permit service authorized to the role contains the service id, the service function will execute.
ServiceA will return a message that declares itself.
Now we use postman to test it. We login as Tom and get back token. Then we request serviceA on path GET /api/secreta with the token. Tom has roleId 1 and roleId 1 has permit services "101, 102". ServiceA id is 101 so Tom is authorized to access serviceA. The postman can get the message sent from serviceA.
If Tom want to access path GET /api/secretc, postman receive not authorized message. It is because serviceC id is 103 and roleId 1's permitService list don't have 103 permission.Now we have completed the implement of authorization check for each protected service. The github link for the code of this practice is provided below the flowchart of checking authorization.
Please leave comments if you have any problem
[1] 原生全端開發使用Node.js 建立最漂亮強大的網站,潘成均著,深智數位股份有限公司出版,2025年1月初版




Comments
Post a Comment