
在laravel中,认证机制的核心是guards(守卫)和providers(提供者)。
默认情况下,Laravel提供一个名为web的Guard(使用session驱动)和一个名为api的Guard(通常使用token驱动,如Sanctum或Passport),它们都使用一个名为users的Provider,该Provider指向App\Models\User模型。当我们需要从多个表认证用户时,就需要扩展这一机制。
要实现对users、students和teachers等多表用户的认证,我们需要为每种用户类型定义独立的Provider,并为API认证定义相应的Guard。
首先,确保你的Student和Teacher模型存在,并且它们都实现了Illuminate\Contracts\Auth\Authenticatable接口。Laravel的User模型默认已经实现了这个接口,你只需让你的自定义用户模型继承Illuminate\Foundation\Auth\User即可,因为它已经实现了该接口。
// app/Models/Student.php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens; // 如果使用Sanctum进行API认证
class Student extends Authenticatable
{
use HasApiTokens, Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
// app/Models/Teacher.php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens; // 如果使用Sanctum进行API认证
class Teacher extends Authenticatable
{
use HasApiTokens, Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}修改config/auth.php文件,添加新的Provider和Guard。
定义Providers: 在providers数组中,为students和teachers添加新的Eloquent provider,指向各自的模型。
// config/auth.php
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'students' => [ // 新增学生Provider
'driver' => 'eloquent',
'model' => App\Models\Student::class,
],
'teachers' => [ // 新增教师Provider
'driver' => 'eloquent',
'model' => App\Models\Teacher::class,
],
],定义Guards: 在guards数组中,为每种用户类型定义一个API Guard。这里我们使用sanctum驱动,它是Laravel 8推荐的API认证方式。每个Guard需要指定其使用的provider。
// config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [ // 默认API Guard,可继续使用或为特定用户类型保留
'driver' => 'sanctum',
'provider' => 'users',
],
'api_student' => [ // 新增学生API Guard
'driver' => 'sanctum',
'provider' => 'students',
],
'api_teacher' => [ // 新增教师API Guard
'driver' => 'sanctum',
'provider' => 'teachers',
],
],现在,你可以在你的控制器中根据用户类型调用相应的Guard进行认证。
登录控制器示例:
假设你有一个AuthController来处理不同用户类型的登录。
// app/Http/Controllers/Api/AuthController.php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
class AuthController extends Controller
{
/**
* 学生登录
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
* @throws \Illuminate\Validation\ValidationException
*/
public function studentLogin(Request $request)
{
$request->validate([
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
]);
if (! Auth::guard('api_student')->attempt($request->only('email', 'password'))) {
throw ValidationException::withMessages([
'email' => [__('auth.failed')],
]);
}
$student = Auth::guard('api_student')->user();
$token = $student->createToken('student-auth-token')->plainTextToken;
return response()->json(['token' => $token, 'student' => $student]);
}
/**
* 教师登录
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
* @throws \Illuminate\Validation\ValidationException
*/
public function teacherLogin(Request $request)
{
$request->validate([
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
]);
if (! Auth::guard('api_teacher')->attempt($request->only('email', 'password'))) {
throw ValidationException::withMessages([
'email' => [__('auth.failed')],
]);
}
$teacher = Auth::guard('api_teacher')->user();
$token = $teacher->createToken('teacher-auth-token')->plainTextToken;
return response()->json(['token' => $token, 'teacher' => $teacher]);
}
/**
* 退出登录 (学生)
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function studentLogout(Request $request)
{
// 确保当前认证用户是学生
if (Auth::guard('api_student')->check()) {
$request->user('api_student')->currentAccessToken()->delete();
return response()->json(['message' => 'Logged out successfully for student.']);
}
return response()->json(['message' => 'Not authenticated as student.'], 401);
}
/**
* 退出登录 (教师)
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function teacherLogout(Request $request)
{
// 确保当前认证用户是教师
if (Auth::guard('api_teacher')->check()) {
$request->user('api_teacher')->currentAccessToken()->delete();
return response()->json(['message' => 'Logged out successfully for teacher.']);
}
return response()->json(['message' => 'Not authenticated as teacher.'], 401);
}
}在routes/api.php中定义路由,并使用相应的Guard中间件来保护它们。
// routes/api.php
use App\Http\Controllers\Api\AuthController;
use Illuminate\Support\Facades\Route;
// 学生认证路由
Route::post('/student/login', [AuthController::class, 'studentLogin']);
Route::middleware('auth:api_student')->group(function () {
Route::get('/student/profile', function (Request $request) {
return $request->user('api_student');
});
Route::post('/student/logout', [AuthController::class, 'studentLogout']);
});
// 教师认证路由
Route::post('/teacher/login', [AuthController::class, 'teacherLogin']);
Route::middleware('auth:api_teacher')->group(function () {
Route::get('/teacher/profile', function (Request $request) {
return $request->user('api_teacher');
});
Route::post('/teacher/logout', [AuthController::class, 'teacherLogout']);
});
// 默认用户认证路由 (如果仍然需要)
Route::post('/user/login', [AuthController::class, 'userLogin']); // 假设你也有一个userLogin方法
Route::middleware('auth:api')->group(function () {
Route::get('/user/profile', function (Request $request) {
return $request->user(); // 默认使用'api' guard
});
});注意: 在middleware('auth:api_student')中,api_student是你在config/auth.php中定义的Guard名称。
通过灵活配置Laravel的Guards和Providers,我们可以轻松地实现对存储在不同数据库表中的多种用户类型进行独立的API认证。这种方法不仅保持了代码的清晰和可维护性,也充分利用了Laravel强大的认证系统,为构建复杂的应用提供了坚实的基础。理解Guards和Providers的工作原理是掌握Laravel认证机制的关键,能够帮助开发者应对各种复杂的认证场景。
以上就是Laravel 8 API 多表用户认证:实现多Guard策略的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号