API Authentication (Passport) 初体验

laravel的api路由默认写了一个api

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

  如果直接访问 /api/user 会重定向到登录页,已登录的也不会正常显示需要的数据,这是因为需要api授权认证才能正常访问。

  为了让服务器支持API授权,体验了一把Passport OAuth 认证,把初次使用这个的过程整理记录一下,也给其它初学者一些经验。

正常的oauth授权流程应该是这样:
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。

  从流程可知oauth授权是需要客户端和服务端二个网站,这里只使用了一个网站:laravel.test,没有使用二个网站来模拟发送请求和授权,基本自己写的路由都是客户端的,服务端不用写啥。

安装

这个完全根据说明文档操作就行,没有任何难度,应该也不会出现任何意外。

composer require laravel/passport
php artisan migrate
php artisan passport:install

安装完成,数据库会生成几张 oauth 前缀的数据表,在 storage 目录下生成 oauth-private.keyoauth-public.key 二个文件,同时会生成二条 oauth client 数据。

前端快速上手

为了方便体验,服务端用户认证系统这里就直接用框架自带的,先安装上:

php artisan make:auth
php artisan migrate

前端使用到 Vue 组件:

php artisan vendor:publish --tag=passport-components

当组件被发布后,按文档在 resources/assets/js/app.js 文件中注册它们,这里我们把认证管理的三个 Vue 组件放到用户认证系统自带的 home.blade.php 中。

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Dashboard</div>

                    <div class="card-body">
                        @if (session('status'))
                            <div class="alert alert-success" role="alert">
                                {{ session('status') }}
                            </div>
                        @endif

                        <passport-clients></passport-clients>
                        <passport-authorized-clients></passport-authorized-clients>
                        <passport-personal-access-tokens></passport-personal-access-tokens>

                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

我们要配置好前端环境,直接 yarn 安装前端组件,然后 npm run dev
注册一个用户登录看看:

配置

发放令牌有指令或客户端两种方式,我们已经使用 vue 组件快速建了客户端,直接点 Create New Client来自己建个。

请求令牌

向服务端应用程序的 /oauth/authorize 路由发出请求,网址参数如下:

http://laravel.test/oauth/authorize?client...=

这里也按文档写一个路由,然后访问 http://laravel.test/redirect 请求令牌:

Route::get('/redirect', function () {
    $query = http_build_query([
        'client_id' => '3',
        'redirect_uri' => 'http://laravel.test/callback',
        'response_type' => 'code',
        'scope' => '',
    ]);

    return redirect('http://laravel.test/oauth/authorize?'.$query);
});

第一次请求时会提示是否授权:

确定授权后,服务端会重定向到回调网址,并传回授权码code。

将授权码转换为访问令牌

文档中是直接在回调路由中使用授权码,换token,这一步需要使用到 client_Secret

Route::get('/callback', function (\Illuminate\Http\Request $request) {
    $http = new GuzzleHttp\Client;

    $response = $http->post('http://laravel.test/oauth/token', [
        'form_params' => [
            'grant_type' => 'authorization_code',
            'client_id' => '3',
            'client_secret' => 'SlxvmfrYl9cRmJpsbojrksfMw8VHUhsZgEpfoc2l',
            'redirect_uri' => 'http://laravel.test/callback',
            'code' => $request->code,
        ],
    ]);

    return json_decode((string)$response->getBody(), true);
});

使用 id 、secret、code等换到token:

现在拿到token了,我们再来访问/api/user试试,写个路由用token向服务端请求数据:

Route::get('/api-test', function (){
    $client = new GuzzleHttp\Client;
    $accessToken = "eyJ0eXAiOiJKV1QiLCJhbG*******6cbwIlrI";
    $response = $client->request('GET', 'http://laravel.test/api/user', [
        'headers' => [
            'Accept' => 'application/json',
            'Authorization' => 'Bearer '.$accessToken,
        ],
    ]);
    return json_decode((string)$response->getBody(), true);
});

客户端访问 http://laravel.test/api-test 试试,正常返回结果啦~

文档中获取授权的token有4种模式,结合这篇文档应该能更好的理解:
http://www.ruanyifeng.com/blog/2014/05/oau...

除了密码授权令牌和直接生成个人Token外,其它授权模式都需要用户登录确定授权。关于直接生成个人令牌的方式,注意图中有一个 Personal Access Tokens ,在客户端直接生成个人Token(不足的是不能设置scope权限范围),但可以直接使用,不需要用授权码换。

为了区分,这里换一个用户登录,然后直接生成Token:

用这个token再授权访问 /api/user 试试:

正常取得用户资料,完美~

在流程测试中以下网址是客户端请求方的,其它全是服务端的。
http://laravel.test/redirect 生成请求授权码的链接用
http://laravel.test/callback 请求回调网址,用来把授权码换成Token令牌
http://laravel.test/api-test 身份验证并请求服务端api(/api/user)的数据

服务端认证路由全部是Passport::routes();注册的,具体路由可以看 vendor/laravel/passport/src/RouteRegistrar.php

其他功能这里就不演示了,只能说很好很强大~

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!