0

0

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

花韻仙語

花韻仙語

发布时间:2025-10-09 08:44:17

|

318人浏览过

|

来源于php中文网

原创

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进行认证。

登录控制器示例:

奇布塔
奇布塔

基于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认证机制的关键,能够帮助开发者应对各种复杂的认证场景。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

319

2024.04.09

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

278

2024.04.09

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

372

2024.04.09

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

374

2024.04.10

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

85

2025.08.05

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

65

2025.08.05

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

68

2025.08.05

什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

178

2024.05.11

php中文乱码如何解决
php中文乱码如何解决

本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

1

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 9.8万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.2万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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