使用 Laravel 7.x 的 Passport 来为 REST API 提供一个完整的 OAuth2 认证服务,第二部分
在这部分我们需要向控制器添加一些路由、一些中间件和一些功能,让我们开始吧
步骤1.修改api.php
我们需要定义三条这样的路由(对于异常处理,我们不需要认证)
<?php
use Illuminate\Support\Facades\Route;
Route::post('login', 'UserController@login');
Route::post('register', 'UserController@register');
Route::get('/unauthorized', 'UserController@unauthorized');
Route::group(['middleware' => ['CheckClientCredentials','auth:api']], function() {
Route::post('logout', 'UserController@logout');
Route::post('details', 'UserController@details');
});
步骤2.给UserController.php添加一些方法
你需要把这些方法加在你的controller里
...
public function details() {
$user = Auth::user();
return response()->json($user, $this->successStatus);
}
public function logout(Request $request) {
$request->user()->token()->revoke();
return response()->json([
'message' => 'Successfully logged out'
]);
}
public function unauthorized() {
return response()->json("unauthorized", 401);
}
...
步骤3.添加中间件
首先添加一个你的中间件
php artisan make:middleware CheckClientCredentials
然后修改CheckClientCredentials.php
<?php
namespace App\Http\Middleware;
use Closure;
use Laminas\Diactoros\StreamFactory;
use Laminas\Diactoros\ResponseFactory;
use Laminas\Diactoros\UploadedFileFactory;
use Laminas\Diactoros\ServerRequestFactory;
use Laravel\Passport\Http\Middleware\CheckCredentials;
use League\OAuth2\Server\Exception\OAuthServerException;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
class CheckClientCredentials extends CheckCredentials
{
public function handle($request, Closure $next, ...$scopes)
{
$psr = (new PsrHttpFactory(
new ServerRequestFactory,
new StreamFactory,
new UploadedFileFactory,
new ResponseFactory
))->createRequest($request);
try {
$psr = $this->server->validateAuthenticatedRequest($psr);
} catch (OAuthServerException $e) {
return response()->json($e->getPayload(), $e->getHttpStatusCode());
}
return $next($request);
}
protected function validateCredentials($token) {}
protected function validateScopes($token, $scopes) {}
}
接下来,需要更改Authenticate.php(用于异常处理)
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string|null
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return '/api/unauthorized';
}
}
}
步骤4.修改Kernel.php
我们需要更改Kernel中的一些内容,并将CheckClientCredentials中间件添加到$routeMiddleware中,然后还要添加到$middlewarePriority中,因为我们需要首先显示CheckClientCredentials!
在$routeMiddleware中添加CheckClientCredentials
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'CheckClientCredentials' => \App\Http\Middleware\CheckClientCredentials::class #changed
];
在$MiddlewarePriority中添加CheckClientCredentials(你在kernel类中没有此变量,有的话应将其覆盖)
protected $middlewarePriority = [
\App\Http\Middleware\CheckForMaintenanceMode::class, #changed
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class
];
步骤5.现在你可以测试了
你可以测试新的url并查看结果
登出
在下一节,我们会尝试实现刷新令牌
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
不知道 public function handle($request, Closure $next, ...$scopes) 中的... 是何解?
下一节在哪