Larave框架如何通过sanctum进行API鉴权

发布时间:2022-07-29 13:41:47 作者:iii
来源:亿速云 阅读:198

Laravel框架如何通过Sanctum进行API鉴权

目录

  1. 引言
  2. Sanctum简介
  3. 安装与配置
  4. 用户认证
  5. API路由保护
  6. 令牌管理
  7. 跨域资源共享(CORS)
  8. 实战案例
  9. 常见问题与解决方案
  10. 总结

引言

在现代Web开发中,API(应用程序编程接口)扮演着至关重要的角色。它们允许不同的应用程序之间进行数据交换和功能调用。然而,随着API的广泛应用,安全性问题也日益突出。为了保护API免受未经授权的访问,开发者需要实现有效的鉴权机制。

Laravel是一个流行的PHP框架,提供了多种方式来实现API鉴权。其中,Sanctum是一个轻量级的包,专门用于为Laravel应用程序提供简单的API鉴权功能。本文将详细介绍如何通过Sanctum在Laravel框架中进行API鉴权。

Sanctum简介

Sanctum是Laravel官方提供的一个轻量级API鉴权包。它主要用于为单页应用(SPA)、移动应用和简单的API提供鉴权功能。Sanctum的核心思想是通过令牌(Token)来验证用户的身份,从而保护API路由。

Sanctum的主要特点包括:

安装与配置

安装Sanctum

要使用Sanctum,首先需要将其安装到Laravel项目中。可以通过Composer来安装Sanctum:

composer require laravel/sanctum

安装完成后,需要发布Sanctum的配置文件和数据迁移文件:

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

配置Sanctum

Sanctum的配置文件位于config/sanctum.php。在这个文件中,可以配置Sanctum的一些基本设置,例如令牌过期时间、令牌前缀等。

return [
    'expiration' => null, // 令牌过期时间,null表示永不过期
    'prefix' => 'sanctum', // 令牌前缀
    'middleware' => [
        'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
        'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
    ],
];

用户认证

创建用户模型

在使用Sanctum之前,首先需要确保项目中有一个用户模型。Laravel默认提供了一个User模型,位于app/Models/User.php。如果项目中没有用户模型,可以通过以下命令创建一个:

php artisan make:model User -m

用户注册与登录

为了实现用户注册和登录功能,可以使用Laravel的Auth系统。首先,确保Auth系统已经启用:

php artisan make:auth

接下来,创建用户注册和登录的路由和控制器:

// routes/web.php
Route::get('/register', 'Auth\RegisterController@showRegistrationForm')->name('register');
Route::post('/register', 'Auth\RegisterController@register');

Route::get('/login', 'Auth\LoginController@showLoginForm')->name('login');
Route::post('/login', 'Auth\LoginController@login');

在控制器中处理用户注册和登录逻辑:

// app/Http/Controllers/Auth/RegisterController.php
public function register(Request $request)
{
    $request->validate([
        'name' => 'required|string|max:255',
        'email' => 'required|string|email|max:255|unique:users',
        'password' => 'required|string|min:8|confirmed',
    ]);

    $user = User::create([
        'name' => $request->name,
        'email' => $request->email,
        'password' => Hash::make($request->password),
    ]);

    event(new Registered($user));

    Auth::login($user);

    return redirect('/home');
}

// app/Http/Controllers/Auth/LoginController.php
public function login(Request $request)
{
    $request->validate([
        'email' => 'required|string|email',
        'password' => 'required|string',
    ]);

    if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
        return redirect()->intended('/home');
    }

    return back()->withErrors([
        'email' => 'The provided credentials do not match our records.',
    ]);
}

API路由保护

创建受保护的路由

在Laravel中,可以通过Sanctum来保护API路由。首先,创建一个API路由组,并使用auth:sanctum中间件来保护这些路由:

// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });

    Route::post('/logout', function (Request $request) {
        $request->user()->currentAccessToken()->delete();
        return response()->json(['message' => 'Logged out']);
    });
});

使用中间件保护路由

在上述代码中,auth:sanctum中间件用于验证用户的身份。如果用户未通过验证,Sanctum将返回401 Unauthorized响应。

令牌管理

生成令牌

在用户登录成功后,可以为用户生成一个API令牌。这个令牌将用于后续的API请求鉴权。

// app/Http/Controllers/Auth/LoginController.php
public function login(Request $request)
{
    $request->validate([
        'email' => 'required|string|email',
        'password' => 'required|string',
    ]);

    if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
        $user = Auth::user();
        $token = $user->createToken('auth_token')->plainTextToken;

        return response()->json([
            'access_token' => $token,
            'token_type' => 'Bearer',
        ]);
    }

    return back()->withErrors([
        'email' => 'The provided credentials do not match our records.',
    ]);
}

撤销令牌

在某些情况下,可能需要撤销用户的API令牌。例如,当用户注销时,可以删除当前的API令牌:

// routes/api.php
Route::post('/logout', function (Request $request) {
    $request->user()->currentAccessToken()->delete();
    return response()->json(['message' => 'Logged out']);
});

跨域资源共享(CORS)

在开发API时,跨域资源共享(CORS)是一个常见的问题。为了允许前端应用访问API,需要在Laravel中配置CORS。

首先,安装fruitcake/laravel-cors包:

composer require fruitcake/laravel-cors

然后,发布CORS配置文件:

php artisan vendor:publish --tag="cors"

config/cors.php中配置CORS策略:

return [
    'paths' => ['api/*'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['*'],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => false,
];

实战案例

创建API

假设我们需要创建一个简单的API,用于管理用户的待办事项。首先,创建一个Task模型和迁移文件:

php artisan make:model Task -m

在迁移文件中定义tasks表的结构:

// database/migrations/xxxx_xx_xx_create_tasks_table.php
public function up()
{
    Schema::create('tasks', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('description')->nullable();
        $table->boolean('completed')->default(false);
        $table->foreignId('user_id')->constrained()->onDelete('cascade');
        $table->timestamps();
    });
}

然后,创建TaskController来处理API请求:

php artisan make:controller TaskController --api

TaskController中实现CRUD操作:

// app/Http/Controllers/TaskController.php
public function index()
{
    return Task::where('user_id', Auth::id())->get();
}

public function store(Request $request)
{
    $request->validate([
        'title' => 'required|string|max:255',
        'description' => 'nullable|string',
    ]);

    $task = Task::create([
        'title' => $request->title,
        'description' => $request->description,
        'user_id' => Auth::id(),
    ]);

    return response()->json($task, 201);
}

public function show(Task $task)
{
    if ($task->user_id !== Auth::id()) {
        return response()->json(['error' => 'Unauthorized'], 403);
    }

    return $task;
}

public function update(Request $request, Task $task)
{
    if ($task->user_id !== Auth::id()) {
        return response()->json(['error' => 'Unauthorized'], 403);
    }

    $request->validate([
        'title' => 'required|string|max:255',
        'description' => 'nullable|string',
        'completed' => 'boolean',
    ]);

    $task->update($request->only(['title', 'description', 'completed']));

    return response()->json($task);
}

public function destroy(Task $task)
{
    if ($task->user_id !== Auth::id()) {
        return response()->json(['error' => 'Unauthorized'], 403);
    }

    $task->delete();

    return response()->json(null, 204);
}

最后,将API路由添加到routes/api.php中:

Route::middleware('auth:sanctum')->group(function () {
    Route::apiResource('tasks', TaskController::class);
});

前端集成

在前端应用中,可以使用axios或其他HTTP客户端来调用API。首先,确保前端应用能够获取到用户的API令牌。

// 登录成功后,保存API令牌
localStorage.setItem('access_token', response.data.access_token);

然后,在每次API请求中,将API令牌添加到请求头中:

axios.defaults.headers.common['Authorization'] = `Bearer ${localStorage.getItem('access_token')}`;

接下来,可以调用API来获取、创建、更新和删除待办事项:

// 获取待办事项列表
axios.get('/api/tasks')
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error(error);
    });

// 创建新的待办事项
axios.post('/api/tasks', {
    title: 'New Task',
    description: 'This is a new task',
})
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error(error);
    });

// 更新待办事项
axios.put('/api/tasks/1', {
    title: 'Updated Task',
    completed: true,
})
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error(error);
    });

// 删除待办事项
axios.delete('/api/tasks/1')
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error(error);
    });

常见问题与解决方案

1. 令牌过期问题

如果令牌设置了过期时间,用户在使用API时可能会遇到令牌过期的问题。为了解决这个问题,可以在前端应用中实现令牌刷新机制。当检测到令牌即将过期时,自动请求新的令牌。

2. 跨域问题

如果前端应用和API部署在不同的域名下,可能会遇到跨域问题。可以通过配置CORS来解决这个问题,确保前端应用能够访问API。

3. 安全性问题

为了增强API的安全性,建议采取以下措施:

总结

通过Sanctum,Laravel提供了一种简单而有效的方式来实现API鉴权。本文详细介绍了如何安装和配置Sanctum,如何实现用户认证和API路由保护,以及如何管理API令牌。通过实战案例,展示了如何创建一个简单的待办事项API,并如何在前端应用中集成API。

Sanctum的轻量级设计和易于集成的特点,使其成为小型项目和简单API鉴权需求的理想选择。然而,对于更复杂的应用场景,可能需要考虑其他更强大的鉴权方案,如Passport。

希望本文能够帮助您更好地理解和使用Sanctum,为您的Laravel应用提供可靠的API鉴权机制。

推荐阅读:
  1. 回源鉴权算法说明
  2. CDH Sentry 管理Hive鉴权

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

larave api

上一篇:基于WPF如何实现一个简单的音频播放动画控件

下一篇:vue cli3配置image-webpack-loader报错怎么解决

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》