使用 Dingo API 扩展包快速构建 Laravel RESTful API(九) —— API 认证实现(下)

栏目: PHP · 发布时间: 5年前

内容简介:在上篇教程中,我们介绍了如何通过 HTTP 基本认证和 JWT 认证实现 Dingo API 的认证,这篇教程,学院君将会给大家介绍如何在 Dingo API 中基于 OAuth 2.0 和自定义认证驱动实现 API 认证。和Laravel Passport 一样,Dingo API 的 OAuth 2.0 认证基于第三方扩展包在这篇教程中,为了简化流程,我们将直接基于 Passport 实现 Dingo API 的 OAuth2 认证(5.3 之前老版本实现可以参考

在上篇教程中,我们介绍了如何通过 HTTP 基本认证和 JWT 认证实现 Dingo API 的认证,这篇教程,学院君将会给大家介绍如何在 Dingo API 中基于 OAuth 2.0 和自定义认证驱动实现 API 认证。

OAuth 2.0 认证

和Laravel Passport 一样,Dingo API 的 OAuth 2.0 认证基于第三方扩展包 league/oauth2-server 实现,该扩展包还提供了针对 Laravel 框架的适配包 lucadegasperi/oauth2-server-laravel ,因此,在 Dingo API 中实现 OAuth 2 认证的话,直接安装配置后面这个扩展包即可。但是从 Laravel 5.3 开始,由于 Laravel 官方提供的 API 认证扩展包 Passport 也是基于 league/oauth2-server 实现的,所以后面这个适配包就废弃了,不仅如此,Dingo API 后续的版本也移除了 OAuth 2 驱动( Dingo\Api\Auth\Provider\OAuth2 ),所以,如果你是在 Dingo API 包含 OAuth2 且 Laravel 框架版本低于 5.3 的老版本中实现 OAuth 2 认证,可以使用 lucadegasperi/oauth2-server-laravel 这个适配包快速实现,否则需要在 Dingo API 中自定义 OAuth2 驱动并自行配置 league/oauth2-server 实现 OAuth 2 认证,或者,你可以直接基于 Passport 实现 Dingo 的认证,包括上篇教程提到的 JWT 认证,也可以基于 Passport 实现(Passport 使用了另一个 JWT 扩展包实现基于 JWT 的 API 认证)。

在这篇教程中,为了简化流程,我们将直接基于 Passport 实现 Dingo API 的 OAuth2 认证(5.3 之前老版本实现可以参考 Dingo 文档 ),关于 OAuth2 的底层原理,可以参考Passport 文档中的介绍,这里我们将重点放到认证实现上。

安装配置 Passport

如果你还没有在项目中安装并初始化 Passport 扩展包的话,可以参考Passport 官方文档进行安装配置。这里由于我们基于待办任务项目进行演示,在之前的教程中已经初始化过,所以可以跳过这一步骤。

最后,记得将 config/auth.php 中的 guards.api.driver 配置值调整为 passport 以便在应用中生效:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

设置认证中间件

基于 Passport 认证的话,就需要修改之前设置的认证中间件了,打开 Api\TaskController.php ,将定义在构造函数中的认证中间件调整为 auth:api

public function __construct()
{
    $this->middleware('auth:api');
}

这样一来,在认证的时候就会通过 Laravel 框架提供的中间件来校验了,此外,还需要修改获取认证用户的代码:

public function index(Request $request)
{
    $limit = $request->input('limit') ? : 10;
    // 获取当前认证用户实例
    $user = $request->user();
    $tasks = Task::where('user_id', $user->id)->paginate($limit);
    return $this->response->paginator($tasks, new TaskTransformer());
}

通过密码授权令牌访问认证 API

OAuth 2 提供了多种获取授权令牌的方法,比如通过授权码颁发访问令牌、密码授权令牌、隐式授权令牌、私人访问令牌等,具体实现可以参考Passport 官方文档或者学院君写的系列教程,这里我们以密码授权令牌为例做演示。

首先,我们通过如下 Artisan 命令创建一个新的需要接入 API 认证的客户端应用:

php artisan passport:client --password

使用 Dingo API 扩展包快速构建 Laravel RESTful API(九) —— API 认证实现(下)

这样一来,我们就获取到对应的 APP ID 和 APP Secret,将其配置到 .env 中:

CLIENT_ID=7
CLIENT_SECRET=7lz6yKdRWudXgwtct6esjwEjk8DpjjFs10lMkvFh

然后我们在 routes/api.php 中定义一个用于获取授权令牌的路由:

$api->version('v3', function ($api) {
    ...
    $api->post('user/token', function () {
        app('request')->validate([
            'email' => 'required|string',
            'password' => 'required|string',
        ]);

        $http = new \GuzzleHttp\Client();
        // 发送相关字段到后端应用获取授权令牌
        $response = $http->post(route('passport.token'), [
            'form_params' => [
                'grant_type' => 'password',
                'client_id' => env('CLIENT_ID'),
                'client_secret' => env('CLIENT_SECRET'),
                'username' => app('request')->input('email'),  // 这里传递的是邮箱
                'password' => app('request')->input('password'), // 传递密码信息
                'scope' => '*'
            ],
        ]);

        return response()->json($response->getBody()->getContents());
    });
    $api->resource('tasks', \App\Http\Controllers\Api\TaskController::class);
});

当我们在 Postman 中模拟访问 user/token 时,就可以获取到对应的访问令牌了:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(九) —— API 认证实现(下)

其中 access_token 就是后续访问认证 API 时需要的令牌。还是在 Postman 中,我们将 access_token 字段值设置到类型为 Bearer 的 Authorization 字段,然后请求 tasks.index 路由,如果能返回相应的响应数据,表示认证成功:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(九) —— API 认证实现(下)

至此,在 Dingo API 中基于 Passport 实现 OAuth2 认证就演示到这里,其它类型的 OAuth2 认证请参考学院君上篇提到的教程自行去实践。

自定义认证驱动

如果以上介绍的 HTTP 基本认证、JWT 认证以及 OAuth2 认证驱动都不能满足你的需求,你还可以选择在 Dingo 中自定义认证驱动。自定义认证驱动类需要实现 Dingo\Api\Contract\Auth\Provider 接口,如果认证成功,则返回对应的认证用户实例,否则要抛出 Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException 异常:

use Illuminate\Http\Request;
use Dingo\Api\Routing\Route;
use Dingo\Api\Contract\Auth\Provider;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;

class CustomProvider implements Provider
{
    public function authenticate(Request $request, Route $route)
    {
        // Logic to authenticate the request.

        throw new UnauthorizedHttpException('Unable to authenticate with supplied username and password.');
    }
}

如果你需要使用从 Authorization 请求头中获取到的令牌,和 Dingo 默认提供的 BasicJWT 驱动一样,可以选择继承 Dingo\Api\Auth\Provider\Authorization 基类,该基类也实现了 Dingo\Api\Contract\Auth\Provider 接口,只是新增了从 Authorization 请求头获取字段值的逻辑,我们在自定义驱动中只需要实现 getAuthorizationMethod 方法来返回 Authorization 请求头的认证类型即可:

use Illuminate\Http\Request;
use Dingo\Api\Routing\Route;
use Dingo\Api\Auth\Provider\Authorization;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;

class CustomProvider extends Authorization
{
    public function authenticate(Request $request, Route $route)
    {
        $this->validateAuthorizationHeader($request);

        // If the authorization header passed validation we can continue to authenticate.
        // If authentication then fails we must throw the UnauthorizedHttpException.
    }

    public function getAuthorizationMethod()
    {
        return 'mac';
    }
}

定义完自定义驱动类就可以在配置文件 config/api.php 中配置通过自定义驱动实现 Dingo API 的认证:

'auth' => [
    'custom' => 'CustomProvider',
],

或者在服务提供者的 boot 方法中扩展 Dingo 认证管理器驱动数组以便在应用中可以通过自定义驱动进行 API 认证:

app(\Dingo\Api\Auth\Auth::class)->extend('custom', function ($app) {
    return new CustomProvider;
});

关于 Dingo API 的认证实现学院君就介绍到这里,下一篇教程我们将开始介绍 API 接口访问频率限制的实现。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Collective Intelligence实战

Collective Intelligence实战

阿拉克 / 2010-9 / 58.00元

《Collective Intelligence实战》内容简介:在互联网上,利用用户的集体智慧是成功的关键。集体智慧是一种新兴的编程技术,可让您从人们访问web和与web交互的过程中找到有价值的模式、发现这些访问者之间的关系和确定他们的个人偏好及习惯等。《collective Intelligence实战》首先介绍了集体智慧的原则和构建更具交互性网站的思想,然后通过示例开发了一个直接可用的基于Ja......一起来看看 《Collective Intelligence实战》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具