Laravel+Angular应用实现用户数据权限控制方案咨询
Got it, let's tackle this permission control step by step. We'll split this into backend (Laravel) and frontend (Angular) parts since the core authorization logic belongs in the backend (never trust frontend-only checks!), and the frontend handles token passing and optional UI adjustments.
Backend (Laravel) Implementation
1. Create a Global Query Scope for Automatic Data Filtering
Instead of repeating the "admin vs regular user" check in every controller method, we'll use a global scope to automatically filter data for non-admin users. This keeps your code DRY.
Create a new scope file at app/Scopes/UserOwnedScope.php:
<?php namespace App\Scopes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Scope; class UserOwnedScope implements Scope { public function apply(Builder $builder, Model $model) { $currentUser = auth()->user(); // Only apply the filter if the user is NOT the admin (id=1) if ($currentUser && $currentUser->id !== 1) { $builder->where('user_id', $currentUser->id); } } }
2. Register the Scope in Your Models
Apply this scope to every model that needs user-specific access (like Shortcode and Smsmo):
For app/Models/Shortcode.php:
<?php namespace App\Models; use App\Scopes\UserOwnedScope; use Illuminate\Database\Eloquent\Model; class Shortcode extends Model { protected $fillable = ['user_id', ...]; // Add your other fillable fields here protected static function boot() { parent::boot(); // Register the global scope static::addGlobalScope(new UserOwnedScope()); } }
Repeat the same setup for your Smsmo.php model.
3. Simplify Your Controller Methods
Now your controller methods can be cleaned up—no more manual checks! The global scope handles filtering automatically:
public function indexShortcode() { // Admin gets all records, regular users get only their own return Shortcode::all(); } public function indexSmsmo() { return Smsmo::all(); }
4. Protect Your API Routes
Make sure all data routes are protected by the auth:api middleware so only authenticated users can access them. Update routes/api.php:
use App\Http\Controllers\ShortcodeController; use App\Http\Controllers\SmsmoController; use App\Http\Controllers\AuthController; Route::post('/login', [AuthController::class, 'login']); Route::post('/register', [AuthController::class, 'register']); // Protected routes (require valid JWT token) Route::middleware('auth:api')->group(function () { Route::get('/me', [AuthController::class, 'me']); Route::post('/logout', [AuthController::class, 'logout']); Route::get('/shortcodes', [ShortcodeController::class, 'indexShortcode']); Route::get('/smsmos', [SmsmoController::class, 'indexSmsmo']); });
5. Implement the /me Endpoint
Add this method to your AuthController to return the current user's data (needed for frontend UI checks):
public function me() { // Returns the authenticated user's full record (including id) return auth()->user(); }
Frontend (Angular) Implementation
1. Add an HTTP Interceptor to Auto-Include JWT Token
Your current code doesn't send the JWT token with API requests, so Laravel can't authenticate the user. Create an interceptor to automatically attach the token to every request:
Create src/app/services/auth.interceptor.ts:
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable } from 'rxjs'; import { AuthService } from './auth.service'; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private authService: AuthService) {} intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { const token = this.authService.getToken(); if (token) { // Clone the request and add the Authorization header request = request.clone({ setHeaders: { Authorization: `Bearer ${token}` } }); } return next.handle(request); } }
Register the interceptor in src/app/app.module.ts:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { AuthInterceptor } from './services/auth.interceptor'; @NgModule({ // ... other imports and declarations providers: [ // ... other providers { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ] }) export class AppModule { }
2. Optional: Use User Data for UI Adjustments
Now that your AuthService fetches the current user via /me, you can use this.authService.currentUser.id to show/hide UI elements for admins. For example, in a component:
// In your component class isAdmin(): boolean { return this.authService.currentUser?.id === 1; }
Then in the template:
<button *ngIf="isAdmin()">Manage All Data</button>
That's it! This setup ensures:
- Admin (id=1) gets full access to all records
- Regular users only see records where
user_idmatches their own - All API requests are authenticated with JWT
- Frontend can adjust UI based on user permissions
内容的提问来源于stack exchange,提问作者user11352561

