Related articles
Blog Building Based on Al egg Framework (1) - Development Preparations
Building Blog Based on Al egg Framework (2) - Hello World
Building Blog Based on Al egg Framework (3) - Registration and Login
Blog Building Based on Al egg Framework (4) - Privilege Control
Building Blog Based on Al egg Framework (5) - Top Navigation Bar
Building Blog Based on Al egg Framework (6) - Browsing and Publishing Articles
Blog Building Based on Al egg Framework (7) - Editing Articles
git
https://github.com/ZzzSimon/e...
Just give me a compliment if you like it.
text
In the last article, we implemented user registration and login, and then we need to control user rights, such as: ordinary users can only comment, administrators can publish articles, top administrators can modify user rights and so on.
Since permission control is a general function, we make this function into middleware. About middleware:
Official documents: https://eggjs.org/zh-cn/basic...
functional design
- A user corresponds to a role
- You can configure pages and interfaces that a role does not have permission to use through configuration files
- You can configure path s that do not need to authenticate users and privileges. For example: related pages and interfaces for login and registration
- The path that can be accessed only after login, otherwise jump to the login page.
User table, add role (role) field
configuration file
We add the following in config/config.default.js:
auth : { noAuth:['/login.htm','/user/login','/register.htm','/user/register'], noPermission:{ admin:[], manager:['/admin.htm'], user:['/admin.htm','/edit.htm'] } }
Among them:
noAuth nodes are configured with path s that can be accessed without authentication
The noPermission node configures path s that each role has no access to
Auh.js middleware code
We create the app/middleware/auth.js file:
module.exports = (options, app) => { return async function auth(ctx, next) { //If user session does not fail if (typeof (ctx.session.user) !== 'undefined') { const username = ctx.session.user.username; //There are two ways to do this. The first way is to check roles every time. The advantages are: real-time, role change is insensitive to users. Disadvantage: Low efficiency of database searching, redis can be considered //The second is to put role information into session, which has the advantage of no need of database search and high efficiency. Disadvantage: Additional logic is needed to handle old sessions when roles change, otherwise the client's user roles cannot be updated in real time. const role = await ctx.service.user.getRoleByUsername(username); const noPerList = options.noPermission[role]; if (noPerList && !noPerList.includes(ctx.path)) { await next(); } else { ctx.body = 'No permission, please contact the webmaster!'; } //No permissions are required to log in to the registration page } else if (options.noAuth.includes(ctx.path)) { await next(); //If session fails, redirect to the login page } else { ctx.redirect('/login.htm') } } };
Effect
We create a user and give him the user role. As can be seen from the configuration file, the user role has no access to the / edit.htm path. As shown in the picture:
Regular matching
If there are more pages, or some paths with parameters are dynamic, we need rules to filter paths. Regular matching is needed at this point. We modify the auth.js file:
module.exports = (options, app) => { function isNoPer(noPerList,path) { for (let i = 0;i<noPerList.length;i++){ const patt=new RegExp(noPerList[i]); if (patt.test(path)) { return true; } } return false; } return async function auth(ctx, next) { //If user session does not fail if (typeof (ctx.session.user) !== 'undefined') { const username = ctx.session.user.username; //There are two ways to do this. The first way is to check roles every time. The advantages are: real-time, role change is insensitive to users. Disadvantage: Low efficiency of database searching, redis can be considered //The second is to put role information into session, which has the advantage of no need of database search and high efficiency. Disadvantage: Additional logic is needed to handle old sessions when roles change, otherwise the client's user roles cannot be updated in real time. const role = await ctx.service.user.getRoleByUsername(username); const noPerList = options.noPermission[role]; if (noPerList && !isNoPer(noPerList,ctx.path)) { await next(); } else { ctx.body = 'No permission, please contact the webmaster!'; } //No permissions are required to log in to the registration page } else if (options.noAuth.includes(ctx.path)) { await next(); //If session fails, redirect to the login page } else { ctx.redirect('/login.htm') } } };
At this point, our configuration file can support regular expressions:
auth : { noAuth:['/login.htm','/user/login','/register.htm','/user/register'], noPermission:{ admin:[], manager:['/admin.htm'], user:['/admin.htm','/edit.*'] } }
Ending
If you find it useful after reading, please give the author a favorite! Thank you!