laravel之passport oauth2认证之授权码详解

包地址

https://packagist.org/packages/laravel/passport#1.0.x-dev
只支持1.0.*

composer require laravel/passport 1.0.*

config/app.php

Laravel\Passport\PassportServiceProvider::class,

生成表

php artisan migrate

laravel之passport oauth2认证之授权码详解_第1张图片
image.png

分析表

oauth_access_tokens 通过认证token表


laravel之passport oauth2认证之授权码详解_第2张图片
image.png

oauth_auth_codes 认证code表


laravel之passport oauth2认证之授权码详解_第3张图片
image.png

oauth_clients认证客户端


laravel之passport oauth2认证之授权码详解_第4张图片
image.png

oauth_personal_access_clients 个人授权客户端


laravel之passport oauth2认证之授权码详解_第5张图片
image.png

oauth_refresh_tokens刷新token表


laravel之passport oauth2认证之授权码详解_第6张图片
image.png

配置

app/auth.php

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

        'api' => [
            'driver' => 'passport',//这里改成passport
            'provider' => 'users',
        ],
    ],

app/User.php
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;

Laravel\Passport\HasApiTokens;

hasMany(Client::class, 'user_id');
    }

    /**
     * 获取用户的所有访问令牌。
     *
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function tokens()
    {
        return $this->hasMany(Token::class, 'user_id')->orderBy('created_at', 'desc');
    }

    /**
     * 获取用户正在使用的当前访问令牌
     *
     * @return \Laravel\Passport\Token|null
     */
    public function token()
    {
        return $this->accessToken;
    }

    /**
     * 确定当前API令牌是否具有给定范围。
     *
     * @param  string  $scope
     * @return bool
     */
    public function tokenCan($scope)
    {
        return $this->accessToken ? $this->accessToken->can($scope) : false;
    }

    /**
     * 为用户创建一个新的个人访问令牌。
     *
     * @param  string  $name
     * @param  array  $scopes
     * @return \Laravel\Passport\PersonalAccessTokenResult
     */
    public function createToken($name, array $scopes = [])
    {
        return Container::getInstance()->make(PersonalAccessTokenFactory::class)->make(
            $this->getKey(), $name, $scopes
        );
    }

    /**
     *为用户设置当前访问令牌

.
     *
     * @param  \Laravel\Passport\Token  $accessToken
     * @return $this
     */
    public function withAccessToken($accessToken)
    {
        $this->accessToken = $accessToken;

        return $this;
    }
}

app/Providers/AuthServiceProvider.php
boot方法中调用Passport::routes方法

 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
        Passport::routes();
        //
    }
}

Passport::routes();
www/laravel53/vendor/laravel/passport/src/Passport.php

public static function routes($callback = null, array $options = [])
    {
        $callback = $callback ?: function ($router) {
            $router->all();
        };
        /*
        *上面等价于
           $callback = $callback ? $callback: function ($router) {
            $router->all();
        };

         */

        $options = array_merge([
            'namespace' => '\Laravel\Passport\Http\Controllers',
            'prefix' => 'oauth',
        ], $options);

        Route::group($options, function ($router) use ($callback) {
            $callback(new RouteRegistrar($router));
        });
    }

如果设置了回调函数,则回调函数的返回自定义的,如果没有,则调用回调函数的所有路由,这里回调了RouteRegistrar这个,这合并传入进来的参数,$options覆盖前面的,

'namespace' => '\Laravel\Passport\Http\Controllers',
'prefix' => 'oauth',

如果你需要全部重写,则修改命名空间和前缀,或者是只修改前缀。

RouteRegistrar的all()

 public function all()
    {
        $this->forAuthorization();
        $this->forAccessTokens();
        $this->forTransientTokens();
        $this->forClients();
        $this->forPersonalAccessTokens();
    }

forAuthorization()注册认证路由

 public function forAuthorization()
    {
        $this->router->group(['middleware' => ['web', 'auth']], function ($router) {
            $router->get('/authorize', [
                'uses' => 'AuthorizationController@authorize',
            ]);

            $router->post('/authorize', [
                'uses' => 'ApproveAuthorizationController@approve',
            ]);

            $router->delete('/authorize', [
                'uses' => 'DenyAuthorizationController@deny',
            ]);
        });
    }

forAccessTokens();注册用于检索和发布访问令牌的路由。

public function forAccessTokens()
    {
        $this->router->post('/token', [
            'uses' => 'AccessTokenController@issueToken',
            'middleware' => 'throttle'
        ]);

        $this->router->group(['middleware' => ['web', 'auth']], function ($router) {
            $router->get('/tokens', [
                'uses' => 'AuthorizedAccessTokenController@forUser',
            ]);
          
            $router->delete('/tokens/{token_id}', [
                'uses' => 'AuthorizedAccessTokenController@destroy',
            ]);
        });
    }

$this->forTransientTokens(); 刷新令牌路由

 public function forTransientTokens()
    {
        $this->router->post('/token/refresh', [
            'middleware' => ['web', 'auth'],
            'uses' => 'TransientTokenController@refresh',
        ]);
    }

$this->forClients();注册管理客户所需的路由。

public function forClients()
    {
        $this->router->group(['middleware' => ['web', 'auth']], function ($router) {
            $router->get('/clients', [
                'uses' => 'ClientController@forUser',
            ]);

            $router->post('/clients', [
                'uses' => 'ClientController@store',
            ]);

            $router->put('/clients/{client_id}', [
                'uses' => 'ClientController@update',
            ]);

            $router->delete('/clients/{client_id}', [
                'uses' => 'ClientController@destroy',
            ]);
        });
    }

$this->forPersonalAccessTokens();注册管理个人访问令牌所需的路由。

public function forPersonalAccessTokens()
    {
        $this->router->group(['middleware' => ['web', 'auth']], function ($router) {
            $router->get('/scopes', [
                'uses' => 'ScopeController@all',
            ]);

            $router->get('/personal-access-tokens', [
                'uses' => 'PersonalAccessTokenController@forUser',
            ]);

            $router->post('/personal-access-tokens', [
                'uses' => 'PersonalAccessTokenController@store',
            ]);

            $router->delete('/personal-access-tokens/{token_id}', [
                'uses' => 'PersonalAccessTokenController@destroy',
            ]);
        });
    }

JSON API

随便找个访问的页面,映入一个JS,例如

Route::get('/rr', function () {
    echo '';
   $a=Auth::user()->toArray();
   print_r($a);
});

通过axios.js来模拟,入门可以看这个https://www.jianshu.com/p/c5b2b281c816

axios.get('/oauth/clients')
    .then(response => {
        console.log(response.data);
    });
image.png

POST /oauth/clients

[图片上传中...(image.png-c74593-1528777113310-0)]

const data = {
    name: 'Client Name',
    redirect: 'http://example.com/callback'
};

axios.post('/oauth/clients', data)
    .then(response => {
        console.log(response.data);
    })
    .catch (response => {
        // List errors on response...
    });

自动将当前登录的帐号写入,这些测试都需要用户登录之后才能操作。否则没有权限访问,因为给了中间件auth

PUT /oauth/clients/{client-id}

const data = {
    name: 'New Client Name',
    redirect: 'http://example.com/callback'
};

axios.put('/oauth/clients/' + clientId, data)
    .then(response => {
        console.log(response.data);
    })
    .catch (response => {
        // List errors on response...
    });
image.png
laravel之passport oauth2认证之授权码详解_第7张图片
image.png

image.png

只是改了name和回调地址

public function update(Request $request, $clientId)
    {
        if (! $request->user()->clients->find($clientId)) {
            return new Response('', 404);
        }

        $this->validation->make($request->all(), [
            'name' => 'required|max:255',
            'redirect' => 'required|url',
        ])->validate();

        return $this->clients->update(
            $request->user()->clients->find($clientId),
            $request->name, $request->redirect
        );
    }

DELETE /oauth/clients/{client-id}

axios.delete('/oauth/clients/' + clientId,data)
    .then(response => {
        console.log(response.data);
    });

请求令牌

这里先新建立一个用户
然后创建一个新的客户端绑定这个用户

php artisan passport:client
[root@localhost laravel53]# php artisan passport:client

 Which user ID should the client be assigned to?:
 > 2

 What should we name the client?:
 > bstbst2

 Where should we redirect the request after authorization? [http://localhost/auth/callback]:
 > http://192.168.91.130:82/auth/callback2

New client created successfully.
Client ID: 11
Client secret: N6Z60B51FRkG2PSyQ9B26v79qJF51NnZo8S6P826

image.png

定义路由
api.php

Route::get('/redirect2', function (){
    $query = http_build_query([
        'client_id' => '11',
        'redirect_uri' => 'http://192.168.91.130:82/auth/callback2',
        'response_type' => 'code',
        'scope' => '',
    ]);

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

web.php

Route::get('/auth/callback2', function (\Illuminate\Http\Request $request) {
   $http = new GuzzleHttp\Client;
   echo $request->get('code');;echo '
'; $response = $http->post('http://192.168.91.130:82/oauth/token', [ 'form_params' => [ 'grant_type' => 'authorization_code', 'client_id' => '11', // your client id 'client_secret' => 'N6Z60B51FRkG2PSyQ9B26v79qJF51NnZo8S6P826', // your client secret 'redirect_uri' => 'http://192.168.91.130:82/auth/callback2', 'code' => $request->get('code'), ], ]); return json_decode((string) $response->getBody(), true); });

现在浏览器打开

http://192.168.91.130:82/api/redirect2
laravel之passport oauth2认证之授权码详解_第8张图片
image.png

服务器返回地址拦带code

http://192.168.91.130:82/auth/callback2?code=def5020071cfabda8770c9e78ed7706f0905ca16a7acd077054aa7570c60d5600b41e7e4c3a2041b2073edd83cf963bacdea9245ba3e47cbc3c65a06118325b7217217b6279cd21016487cbbf00cb5ce95092edb9c341d5f7eeab9000a050d8a2ed6ae6e0f32ca2146c6cbdb414142be035369244e4e4df5e83511a80679d988bbfccf54533f0aadf3b983db764192086bf4175484bc34b5dc21d5a9ba3b41b63bcd170dbedde5a9bd131e720f2b62d17ca0d25461f13398b7f249121f256a610cb8b931fbfcd5b89bd5bd603b712a4ad977b2d6b3f2b9c29fa119efd26339771dd119ad483e12aae7a4fa9ab8a5614bb239d117fe6431022cef0166cf2a9d922fbdb99ef0bad035188283e6f2b7973bf3de103d1097184031223a9b743f558f86130e250b6f6236c981ec913620ff290aef7e70007f01c9c8188686fcd9cbd31fa90da1ee0107065bf46b1486e3b746d06535a33ba04e5dbb24ad4b46dbab1e258779606ec505b8a0c8cc19cb

因为我们再回调里面直接写了,post过去认证,这里返回

{
    "token_type": "Bearer",
    "expires_in": 31535999,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjJhNThkZDdiZjIxNGZkYjY1MDVmODkxMWUxZTFkODFjMjdmNzEzOTVkYmM4MmM5ODgwNGI0ZmYxYjkzZDVlZmI3ODk1N2IzYzVlMDNlZTQ0In0.eyJhdWQiOiIxMSIsImp0aSI6IjJhNThkZDdiZjIxNGZkYjY1MDVmODkxMWUxZTFkODFjMjdmNzEzOTVkYmM4MmM5ODgwNGI0ZmYxYjkzZDVlZmI3ODk1N2IzYzVlMDNlZTQ0IiwiaWF0IjoxNTI4NzkyMjExLCJuYmYiOjE1Mjg3OTIyMTEsImV4cCI6MTU2MDMyODIxMSwic3ViIjoiMiIsInNjb3BlcyI6W119.GQBOIlXnQAIMMAEDwaR8NpOumTeIm9JD3MkTZl_VMek_KcGT5P7Bwuj5tMV-k1-tXUp4u_-iLrAhzfT-1BymywaZNwsiSu0Ehzs6V0d22JIRzY0EkT4gfuRLw51AjiB5zUSlSjEqulRY8NFjplcSDidDopzIwpB-YzWCvB8RZ0NXZcdLxfTN4cUcYIlI3UMorGM_7lGecZ-LVc0ZQ6GzDsteC-Cbhnlcy7oT_xY-aGyNLgfAe_ZP2qofiZv22ufdnypcdg7CtHWM9oAiUhssdO8imvAW00Y3h0K8nQVDVcC9N5v93TfxeED376pVoFYSgR9vjzPtMOKtu7irHjVv_Og1cyt83i5-betgO_URMvBTD986MZ5N7-5bfp_WG416JaeNy3xhK1m-t_SBdb71_9w8uo25KsPwfsAGTE1HAO-jb2ntcYnlcVLfR0_c7AXWTluLGnYvwWyyr76JIDMEunfp4i9Qzuzcj2dcbt1VrlLDSGuhGD8PRSdrCJQUs95M06IMaWtz73w_rxJxfDNmX4Q17mrbREncBpmhbuZ6JzOdWcC2F8T5D3OJJpghDKj6TvNMG97ZDMIPaesAG0OPFXf2U_wLCWOB-PXW92wRQufWgZJUcHekX7C6CVDdT2FyXCMvu_9pt_4ZSIRnQwrfOOfKGf1U7UU6VLtv5THsDiI",
    "refresh_token": "def5020057c3a82b1607265f777db6ba75cd10dc4aa10eda4271a814d613ca5af6a032be9697e91d1ce4f792bf32a4a77734babc9ab94ded306f32f05ebe98735c0858652d7eb5ad1e2c02a665df38149fe2f53df19ebbc76afcdb31d00284fa4a22c3b17da4d5d3db9719f0e9de6739154406aae7e55d40ef4d4e06d28a949e77ce6fa7166403e1bd0e728b76dbae85d78b86b0f39765466c13a17a40bd086a99c821b9222b3e93540e3c2b4c63da59a10017ce96a0166a26596f23cd6710aee5ed0723d2ceee65b9a41a2515a29d10488c0650d8978c4e3669022bb83e0503d552120071ff7b08ac81c70b83a5463a7f1d451cbcf423e0493d5e3b71754325c10056415aaf5696cd5010cc0dcdd44c73a011795c91da6c87555e4d6eccf9eb5a9482a47911d7983936d3d5fed3b6765766e5871d4e9dbb4d07c58b6de309e99f56433b0e3170718797e31e22f5a2afe315188d17b70c4060d386e6da9bd33c66e5"
}

这个时候看下数据库,以下截图是后来补的,可能跟之前的客户端对不上,之前是11,现在是13,这里参考下就行
刷新token表


laravel之passport oauth2认证之授权码详解_第9张图片
image.png

有效期默认是365天,今天是6-12号
token表


laravel之passport oauth2认证之授权码详解_第10张图片
image.png

认证码表
laravel之passport oauth2认证之授权码详解_第11张图片
image.png

如果你想定义刚才那个授权界面,可以
发布的视图位于 resources/views/vendor/passport:

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

刷新令牌

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

    $response = $http->post('http://laravel55.dev/oauth/token', [
        'form_params' => [
            'grant_type' => 'authorization_code',
            'client_id' => '11',  // your client id
            'client_secret' => 'N6Z60B51FRkG2PSyQ9B26v79qJF51NnZo8S6P826',   // your client secret
            'redirect_uri' => 'http://192.168.91.130:82/auth/callback',
            'code' => $request->code,
        ],
    ]);

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

以上是code授权oauth2.0
下一篇讲密码授权令牌

你可能感兴趣的:(laravel之passport oauth2认证之授权码详解)