Laravel 8 API 多表用户认证:实现多Guard策略

花韻仙語
发布: 2025-10-09 08:44:17
原创
306人浏览过

Laravel 8 API 多表用户认证:实现多Guard策略

本教程旨在解决Laravel 8 API中如何对存储在不同数据库表中的多种用户类型(如学生、教师)进行认证的问题。我们将深入探讨Laravel灵活的认证机制,通过配置多Guards和Providers,实现对不同用户模型进行独立且安全的API认证,并提供详细的配置与代码示例。

理解Laravel认证核心:Guards与Providers

laravel中,认证机制的核心是guards(守卫)和providers(提供者)。

  • Guards 负责定义用户如何被认证和存储(例如,通过session、token、JWT等)。它决定了用户登录后如何保持认证状态。
  • Providers 负责从持久化存储(通常是数据库)中检索用户数据。它定义了如何根据用户ID或凭据(如邮箱和密码)找到对应的用户记录。

默认情况下,Laravel提供一个名为web的Guard(使用session驱动)和一个名为api的Guard(通常使用token驱动,如Sanctum或Passport),它们都使用一个名为users的Provider,该Provider指向App\Models\User模型。当我们需要从多个表认证用户时,就需要扩展这一机制。

实现多表用户认证的步骤

要实现对users、students和teachers等多表用户的认证,我们需要为每种用户类型定义独立的Provider,并为API认证定义相应的Guard。

1. 创建用户模型并实现Authenticatable接口

首先,确保你的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',
    ];
}
登录后复制

2. 配置认证Guards和Providers

修改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',
    ],
],
登录后复制

3. 实现API认证逻辑

现在,你可以在你的控制器中根据用户类型调用相应的Guard进行认证。

登录控制器示例:

Robovision AI
Robovision AI

一个强大的视觉AI管理平台

Robovision AI 65
查看详情 Robovision AI

假设你有一个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);
    }
}
登录后复制

4. 定义API路由并使用中间件保护

在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名称。

注意事项

  1. 选择合适的API认证驱动: 本教程示例使用了Laravel Sanctum,它是一个轻量级的API认证包,适用于SPA、移动应用和简单的API token认证。如果你需要更强大的OAuth2功能,可以考虑使用Laravel Passport。
  2. 模型必须实现Authenticatable: 确保所有需要认证的用户模型都继承了Illuminate\Foundation\Auth\User或手动实现了Illuminate\Contracts\Auth\Authenticatable接口。
  3. 密码哈希: 在将用户密码存入数据库之前,务必使用bcrypt()或其他安全的哈希算法进行哈希处理。Laravel的User模型通常会在创建时自动处理。
  4. 错误处理: 在认证失败时,提供清晰的错误信息,避免暴露过多内部细节。
  5. 前端交互: 客户端在登录成功后应保存返回的API token,并在后续请求中通过Authorization: Bearer {token}头发送该token。

总结

通过灵活配置Laravel的Guards和Providers,我们可以轻松地实现对存储在不同数据库表中的多种用户类型进行独立的API认证。这种方法不仅保持了代码的清晰和可维护性,也充分利用了Laravel强大的认证系统,为构建复杂的应用提供了坚实的基础。理解Guards和Providers的工作原理是掌握Laravel认证机制的关键,能够帮助开发者应对各种复杂的认证场景。

以上就是Laravel 8 API 多表用户认证:实现多Guard策略的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号