如何在SailsJS 1.2.3中为蓝图路由实现行级权限?
Great question—since the older sails-auth and sails-permissions packages don’t support Sails 1.x, you’ll need to leverage Sails’ built-in features to add row-level permissions while keeping blueprint routes intact. I’ve implemented this successfully for several projects, and here are the most practical approaches:
1. Use Sails Policies to Filter Blueprint Queries
Policies are Sails’ core way to handle authorization, and they work seamlessly with blueprint routes. The idea is to inject a filter into the request’s query conditions based on the user’s role before the blueprint action runs.
Example Implementation:
First, create a policy that modifies the where clause for non-admin users:
// api/policies/filterByUserPermissions.js module.exports = async function (req, res, next) { // Bypass filter if user is an admin if (req.user?.role === 'admin') { return next(); } // Initialize where clause if it doesn't exist req.options.where = req.options.where || {}; // For regular users, limit results to records they own (adjust based on your model) // Assuming your model has an `owner` field linked to the user's ID req.options.where.owner = req.user.id; // If you need more complex rules (e.g., editors can view their department's records), add them here // if (req.user?.role === 'editor') { // req.options.where.department = req.user.department; // } next(); };
Then, bind this policy to the blueprint actions of your models in config/policies.js:
module.exports.policies = { // Ensure all routes require authentication first (use your existing auth policy) '*': 'isAuthenticated', // Apply the permission filter to specific model blueprint actions 'Post': { find: 'filterByUserPermissions', findOne: 'filterByUserPermissions', update: 'filterByUserPermissions', destroy: 'filterByUserPermissions' }, // Repeat for other models needing row-level access 'Comment': { find: 'filterByUserPermissions', findOne: 'filterByUserPermissions' } };
This approach is lightweight, maintainable, and uses only Sails’ native tools—no extra dependencies required.
2. Customize Blueprint Actions for Complex Rules
If you need more granular control (e.g., dynamic permissions based on record attributes or group membership), you can override the default blueprint actions directly.
How to Do It:
- Copy the default blueprint action from
node_modules/sails/lib/hooks/blueprints/actions/(e.g.,find.js) intoapi/blueprints/in your project. - Modify the copied file to add your permission logic before the database query runs.
Example modified find.js blueprint:
// api/blueprints/find.js module.exports = async function findRecords(req, res) { // ... keep most of the original blueprint code here ... // Add permission filtering before building the query if (req.user?.role !== 'admin') { const userRole = req.user.role; // Complex rule: Editors see their department's records; regular users see only their own if (userRole === 'editor') { criteria.where.department = req.user.department; } else { criteria.where.owner = req.user.id; } } // ... continue with the original query execution ... };
This gives you full control over the blueprint logic, but keep in mind you’ll need to maintain these custom files if you update Sails.
3. Key Additional Tips
- Authentication First: Make sure you have a working auth system (e.g., Passport.js integrated with Sails) so
req.useris populated with the user’s role and other relevant data. - Lifecycle Hooks for Creation: For
createactions, automatically set theowneror permission-related fields using model lifecycle hooks likebeforeCreate:// api/models/Post.js module.exports = { attributes: { /* ... your attributes ... */ }, beforeCreate: function (valuesToSet, proceed) { // Set the owner to the current user valuesToSet.owner = this.req.user.id; return proceed(); } }; - Validate Update/Destroy Access: Even with query filtering, add an extra check in policies for
update/destroyto ensure the user actually owns the record (in case the query filter is bypassed accidentally).
内容的提问来源于stack exchange,提问作者sbenner

