包地址
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
分析表
oauth_access_tokens 通过认证token表
oauth_auth_codes 认证code表
oauth_clients认证客户端
oauth_personal_access_clients 个人授权客户端
oauth_refresh_tokens刷新token表
配置
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);
});
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...
});
只是改了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
定义路由
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
服务器返回地址拦带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表
有效期默认是365天,今天是6-12号
token表
认证码表
如果你想定义刚才那个授权界面,可以
发布的视图位于 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
下一篇讲密码授权令牌