在 API 场景里通常通过令牌来实现用户授权,而非维护请求之间的 Session 状态。
在 Laravel 项目中使用 Passport 可以轻而易举地实现 API 授权认证,Passport 可以在几分钟之内为你的应用程序提供完整的 OAuth2 服务端实现。
安装:
composer require laravel/passport
Passport 服务提供器使用框架注册自己的数据库迁移目录
因此在注册提供器后,就应该运行 Passport 的迁移命令来自动创建存储客户端和令牌的数据表:
php artisan migrate
Passport默认是提供一个全功能的OAuth授权系统,如果不需要,
1. 首先在php artisan migrate
执行之前添加一个方法到app/Providers/AppServiceProvider的register()方法中:
LaravelPassportPassport::ignoreMigrations();2.在app/Http/Kernel内的’web’配置里添加:'web' => [ ... LaravelPassportHttpMiddlewareCreateFreshApiToken::class, ]这个会在以后的web请求中,添加一个laravel_token字段到cookie中。参考:Consume Laravel APIs from VueJS with Passport
接下来,运行 passport:install
命令来创建生成安全访问令牌时所需的加密密钥
同时,这条命令也会创建用于生成访问令牌的「个人访问」客户端和「密码授权」客户端:
php artisan passport:install
上面命令执行后,请将 LaravelPassportHasApiTokens
Trait 添加到 AppUser
模型中
这个 Trait 会给你的模型提供一些辅助函数,用于检查已认证用户的令牌和使用范围:
接下来,在 AuthServiceProvider
的 boot
方法中调用 Passport::routes
函数。这个函数会注册发出访问令牌并撤销访问令牌、客户端和个人访问令牌所必需的路由:
最后,将配置文件 config/auth.php 中授权看守器 guards 的 api 的 driver 选项改为 passport。此调整会让你的应用程序在在验证传入的 API 的请求时使用 Passport 的 TokenGuard 来处理:
更多内容:
https://learnku.com/docs/laravel/7.x/passport/7515
https://learnku.com/laravel/t/20144
关于jwt
【Day 2】Create Laravel Project & Json Web Token
Laravel 使用 JWT 实现 API Auth, 打造用户授权接口
关于Passport运用:
Laravel 5.7 — API authentification with Laravel Passport
VueJs Consumer App – Laravel API with Passport
参考 Laravel 5.7 — API authentification with Laravel Passport 后:
注意:由于我们在migrate的时候采用了默认的设置,有很多数据表都没有用上,建议以后自定义一下。
执行
php artisan make:controller Api/AuthController
AuthController中我们只对Personal Access Token执行操作,关于Personal Access Token参考:个人访问令牌
代码如下:
<?php namespace AppHttpControllersApi; use AppHttpControllersController; use AppUser; use IlluminateHttpRequest; use IlluminateSupportFacadesHash; use IlluminateSupportFacadesValidator; class AuthController extends Controller { //https://medium.com/@martin.riedweg/laravel-5-7-api-authentification-with-laravel-passport-92b909e12528 public function register(Request $request) { $validator = Validator::make($request->all(), [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:6|confirmed', ]); if ($validator->fails()) { return response([ 'errors' => $validator->errors()->all() ], 422); } $request['password'] = Hash::make($request['password']); $user = User::create($request->toArray()); $token = $user->createToken('Laravel Password Grant Client')->accessToken; $response = ['token' => $token]; return response($response, 200); } public function login(Request $request) { $user = User::where('email', $request->email)->first(); if ($user) { if (Hash::check($request->password, $user->password)) { $token = $user->createToken('Laravel Password Grant Client')->accessToken; $response = ['token' => $token]; return response($response, 200); } else { $response = "Password missmatch"; return response($response, 422); } } else { $response = "User does not exist"; return response($response, 422); } } public function logout(Request $request) { $token = $request->user()->token(); $token->revoke();//disable trash the token $response = "You have been successfully logged out!"; return response($response, 200); } }
api.php修改如下:
<?php use IlluminateHttpRequest; use IlluminateSupportFacadesRoute; /* |-------------------------------------------------------------------------- | API Routes |-------------------------------------------------------------------------- | | Here is where you can register API routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | is assigned the "api" middleware group. Enjoy building your API! | */ Route::middleware('auth:api')->get('/user', function (Request $request) { return $request->user(); }); Route::middleware('auth:api')->get('/user', function (Request $request) { return $request->user(); }); Route::post('login', 'ApiAuthController@login')->name('login.api'); Route::post('register', 'ApiAuthController@register')->name('register.api'); Route::middleware('auth:api')->get('logout', 'ApiAuthController@logout')->name('logout.api');
通过在PostMan中测试 结果如下:
注册请求:
将返回的token复制一下 登录请求的Authorization中,选择Bearer Token,将复制的Token粘贴到Token输入框中:
然后在body中键入email 及 password字段及其值,然后发送post请求。
登录请求:
复制登录成功后response中的token值。
粘贴到退出登录请求的Bearer Token中:
退出登录请求:
发送get请求,结果如下:
再来看看数据库中的数据:
用户表:
access_token表:
因为我们注册时后台返回的token我们只是来进行了登录 ,逻辑上没有将注册返回的token来revoke作废掉,所以user_id为3的用户的token revoked为0【未作废】,但是登录后返回的token我们执行了logout,通过AuthController中logout方法把登录的token作废了,所以表中revoked为1【作废了】。