使用 Dingo API 扩展包快速构建 Laravel RESTful API(八) —— API 认证(上)

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

内容简介:有些 API 接口需要用户认证之后才能返回响应,有些 API 接口则会根据用户认证与否返回不同的响应数据,Dingo 扩展包支持多个不同的认证驱动,在 Dingo API 中启用认证后,当我们尝试对请求进行认证时就会执行对应的驱动逻辑。下面是 Dingo 开箱支持的认证驱动:其实 Laravel 框架提供的 API 认证解决方案 Passport 无非也是对 JWT 和 OAuth2 的封装,Dingo API 只是自己单独实现了一套 API 认证机制而已,除此之外,Dingo 扩展包还支持自定义认证驱动,

概述

有些 API 接口需要用户认证之后才能返回响应,有些 API 接口则会根据用户认证与否返回不同的响应数据,Dingo 扩展包支持多个不同的认证驱动,在 Dingo API 中启用认证后,当我们尝试对请求进行认证时就会执行对应的驱动逻辑。下面是 Dingo 开箱支持的认证驱动:

  • HTTP 基本认证(Basic)
  • JSON Web Tokens(JWT)
  • OAuth 2.0(OAuth2)

其实 Laravel 框架提供的 API 认证解决方案 Passport 无非也是对 JWT 和 OAuth2 的封装,Dingo API 只是自己单独实现了一套 API 认证机制而已,除此之外,Dingo 扩展包还支持自定义认证驱动,下面我们将逐个介绍这些不同认证驱动的实现和使用。

HTTP 基本认证

注册驱动

在 Dingo API 中通过 HTTP 基本认证实现对请求的认证很简单,首先我们需要在 AuthServiceProviderboot 方法将基本认证注册到 Dingo 的认证管理器中:

use Dingo\Api\Auth\Auth;
use Dingo\Api\Auth\Provider\Basic;

public function boot()
{
    ...

    // Dingo 认证驱动注册
    $this->app->make(Auth::class)->extend('basic', function ($app) {
        return new Basic($app['auth'], 'email');
    });
}

这里我们指定 basic 驱动对应的实现类为 Dingo\Api\Auth\Provider\Basic ,并且以用户邮箱字段作为认证唯一标识。

认证中间件

然后,就可以在相应的 API 路由中通过认证中间件标识该路由需要认证之后才能访问:

$api->version('v3', ['middleware' => 'api.auth'], function ($api) {
    $api->resource('tasks', \App\Http\Controllers\Api\TaskController::class);
});

这样定义的话,会让 Dingo 认证中间件作用到 v3 版本下的所有 Dingo API 接口,如果只想在指定路由上应用该中间件的话,可以这么做:

$api->version('v3', function ($api) {
    $api->resource('tasks', \App\Http\Controllers\Api\TaskController::class, [
        'middleware' => 'api.auth'
    ]);
});

当然,你还可以在控制器中定义中间件:

class TaskController extends ApiController
{
    public function __construct()
    {
        $this->middleware('api.auth');
    }

    ...

}

访问认证接口

接下来,我们就可以访问需要认证的 API 接口了,访问 tasks.index 路由对应的 URL,如果没有认证的话会返回 401 Unauthorized 响应:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(八) —— API 认证(上)

而如果添加 Basic 认证头之后,就可以正常访问这个 API 接口了,添加 Basic 认证头可以通过在 Postman 的 Authorization 标签页中设置实现,选择认证类型为 Basic Auth ,然后在右侧表单输入认证凭证(我们在设置驱动的时候指定以邮箱作为认证标识,所以这里用户名字段输入邮箱信息):

使用 Dingo API 扩展包快速构建 Laravel RESTful API(八) —— API 认证(上)

发起请求,就可以正常返回响应数据了:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(八) —— API 认证(上)

获取认证用户信息

如果你想要在应用代码中获取认证用户信息,可以这么做:

use Dingo\Api\Auth\Auth;

$user = app(Auth::class)->user();

我们可以改写 Api\TaskControllerindex 方法如下,只获取当前认证用户名下的任务信息:

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

在引入了 Dingo\Api\Routing\Helpers Trait 的类中,还可以通过 $this->auth->user() 获取当前认证用户。

JWT 认证

安装 JWT 扩展包

HTTP 基本认证虽然简单,但是不够安全,因为密码信息只是通过 Base64 进行编码,相当于明文传输,所以并不推荐,为此我们引入了 JSON Web Tokens,简称 JWT,关于 JWT 认证的原理可以参考 Laravel 5 中使用 JWT 实现基于 API 的用户认证 这篇教程,Dingo 中基于 JWT 的认证同样也是基于里面提到的 tymon/jwt-auth 扩展包。所以在使用该认证驱动之前,先要通过 Composer 安装这个依赖:

composer require tymon/jwt-auth

安装完成后将配置文件发布到 config 目录下:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"

最后通过如下 Artisan 命令生成 JWT 的密钥用于后续生成 Token:

php artisan jwt:secret

在继续后续步骤之前,还要让用于认证的 User 模型类实现 JWTSubject 接口,以便可以通过 JWT 进行认证:

use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    ...

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

注册驱动

然后我们可以在 config/api.php 中注册对应的认证驱动:

'auth' => [
    'jwt' => \Dingo\Api\Auth\Provider\JWT::class,
],

或者和 HTTP 基本认证一样,在 AuthServiceProviderboot 方法中通过如下方式注册:

use Dingo\Api\Auth\Auth;
use Dingo\Api\Auth\Provider\JWT;
use Tymon\JWTAuth\JWTAuth;

$this->app->make(Auth::class)->extend('jwt', function ($app) {
    return new JWT($app[JWTAuth::class]);
});

获取 JWT 令牌

注册认证中间件和 HTTP 基本认证一样,并没有什么区别,只是访问 API 接口的认证方式不一样而已,在通过 JWT 进行认证之前,先要获取 JWT 令牌值,我们可以编写一个 API 接口来获取:

$api->version('v3', function ($api) {
    $api->post('user/auth', function () {
        $credentials = app('request')->only('email', 'password');
        try {
            if (! $token = \Tymon\JWTAuth\Facades\JWTAuth::attempt($credentials)) {
                throw new \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException('Invalid credentials');
            }
        } catch (\Tymon\JWTAuth\Exceptions\JWTException $e) {
            throw new \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException('Create token failed');
        }

        return compact('token');
    });

    ...
});

在 Postman 中访问该路由,即可获取到 Token 值:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(八) —— API 认证(上)

基于 JWT 认证访问 API

有了 JWT 令牌值,就可以通过在请求头中设置该令牌值实现 JWT 认证了,其它代码保持和 HTTP 基本认证一样,我们在 Postman 中设置认证类型为 Bearer Token,并将上一步获取到的 Token 值设置到右侧的 Token 字段中:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(八) —— API 认证(上)

然后访问 tasks.index 路由,就可以成功获取到该用户名下的任务列表了:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(八) —— API 认证(上)

至此,基于 JWT 认证的 API 接口就已经实现了,下一篇我们将继续介绍如何基于 OAuth 2.0 实现 Dingo API 的认证。


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

查看所有标签

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

Numerical Methods and Methods of Approximation in Science and En

Numerical Methods and Methods of Approximation in Science and En

Karan Surana / CRC Press / 2018-10-31

ABOUT THIS BOOK Numerical Methods and Methods of Approximation in Science and Engineering prepares students and other readers for advanced studies involving applied numerical and computational anal......一起来看看 《Numerical Methods and Methods of Approximation in Science and En》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具