Laravel中客户与员工门户的独立授权方案咨询
Hey there! Let's walk through how to implement separate authorization for your restaurant ordering platform—since you've got two linked but basically independent portals (customer vs. employee) with different data stores and login requirements, the key is to keep their auth flows isolated while still letting them work together where needed.
First off, don't force a shared user model—since your customers and employees have entirely separate data tables, keeping their identities distinct will avoid all kinds of confusion down the line. Here's a step-by-step breakdown:
1. Build Separate Identity Entities & Database Tables
- Create a
customerstable with customer-specific fields: things likeemail/phone_number,default_delivery_address,loyalty_points, plus a mandatorypassword_hashfield (always use a strong hashing algorithm like bcrypt). - Create an
employeestable for staff: include fields likeemployee_id,department(kitchen/front desk/management),role(admin/regular staff),assigned_store, and again apassword_hashfield. - If you need to manage employee groups for bulk permissions, add extra tables like
employee_groupsandemployee_group_membersto link staff to their respective permission sets.
2. Independent Login Entries & Authentication Logic
- Build completely separate login pages for each portal: the customer login only needs email/phone + password, while the employee login might require additional verification like
employee_id+ password + store selection. - Write dedicated authentication controllers for each type:
- Customer auth: Only query the
customerstable, validate credentials, then generate a session explicitly marked asuser_type: 'customer'. - Employee auth: Query the
employeestable, add pre-checks for role permissions (e.g., only admins can access the staff management backend), then generate a session withuser_type: 'employee'plus role/store details.
- Customer auth: Only query the
- Example pseudo-code (using Node.js/Express for context):
// Customer login controller async function customerLogin(req, res) { const { email, password } = req.body; const customer = await Customer.findOne({ where: { email } }); if (!customer || !await bcrypt.compare(password, customer.password_hash)) { return res.status(401).send('Invalid email or password'); } // Store customer-specific session data req.session.user = { id: customer.id, type: 'customer', email: customer.email }; res.redirect('/customer/dashboard'); } // Employee login controller async function employeeLogin(req, res) { const { employee_id, password, store_id } = req.body; const employee = await Employee.findOne({ where: { employee_id, store_id } }); if (!employee || !await bcrypt.compare(password, employee.password_hash)) { return res.status(401).send('Invalid credentials or store mismatch'); } // Include role data for granular permission checks later req.session.user = { id: employee.id, type: 'employee', role: employee.role, store_id: employee.store_id }; res.redirect('/employee/dashboard'); }
3. Route-Level Permission Isolation
- Add portal-specific middleware to protect routes:
- Customer route middleware: Check that the session has
user_type: 'customer'—if not, redirect to the customer login page or return a 403 error. - Employee route middleware: Verify the session is marked as
employee, and optionally filter access by role (e.g., only admins can access staff management pages).
- Customer route middleware: Check that the session has
- Example middleware implementations:
// Middleware to protect customer-only routes function requireCustomer(req, res, next) { if (req.session.user?.type === 'customer') { return next(); } res.redirect('/customer/login'); } // Middleware to protect employee routes with role-based access function requireEmployee(allowedRoles = []) { return (req, res, next) => { if (!req.session.user || req.session.user.type !== 'employee') { return res.redirect('/employee/login'); } if (allowedRoles.length && !allowedRoles.includes(req.session.user.role)) { return res.status(403).send('You don\'t have permission to view this page'); } next(); }; } // Route configuration example app.get('/customer/orders', requireCustomer, customerOrdersController); app.get('/employee/manage-staff', requireEmployee(['admin']), manageStaffController);
4. Permission Controls for Shared Resources (If Needed)
If both portals need access to shared resources (like menu items), add logic at the data layer to filter based on user type:
- For example, customers should only see published menu items, while employees can view all items (including unpublished drafts):
async function getMenuItems(req) { const filter = {}; if (req.session.user?.type === 'customer') { filter.is_published = true; } return MenuItem.findAll({ where: filter }); }
5. Critical Security Notes
- Isolate sessions: Use different cookie names for customer and employee sessions (e.g.,
customer_sessionandemployee_session) to prevent cross-portal session confusion. - Enforce strong password rules: Require more complex passwords for employees (e.g., minimum 8 characters, mix of letters, numbers, and symbols) compared to customers if needed.
- Add brute-force protection: Limit failed login attempts for both portals (e.g., lock an account for 15 minutes after 5 failed tries) to prevent attacks.
内容的提问来源于stack exchange,提问作者sursider

