avatar

Laravel+Passport构建API系统

Laravel+Passport构建API系统

安装Laravel

composer global require laravel/installer
laravel new project

配置nginx站点信息

sudo vim /etc/nginx/sites-available/laravel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
server {
listen 443 ssl;

ssl_certificate /etc/nginx/sites-available/ssl.crt;
ssl_certificate_key /etc/nginx/sites-available/ssl.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

root /home/pwfu/Documents/project/public/;
index index.html index.htm index.php;
server_name laravel.test api.laravel.test m.laravel.test www.laravel.test;
#server_name localhost;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
error_page 404 /index.php;
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
}

sudo service nginx restart

安装Passport

composer require laravel/passport
php artisan migrate
php artisan passport:install
sudo chmod 777 -R bootstrap/cache
sudo chmod 777 -R storage

上面命令执行后,请将 Laravel\Passport\HasApiTokens Trait 添加到 App\User 模型中,这个 Trait 会给你的模型提供一些辅助函数,用于检查已认证用户的令牌和使用范围:

1
2
3
4
5
6
7
8
9
10
11
12
<?php

namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
use HasApiTokens, Notifiable;
}

接下来,在 AuthServiceProvider 的 boot 方法中调用 Passport::routes 函数。这个函数会注册发出访问令牌并撤销访问令牌、客户端和个人访问令牌所必需的路由:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php

namespace App\Providers;

use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
/**
* 应用程序的策略映射。
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];

/**
* 注册认证 / 授权服务
*
* @return void
*/
public function boot()
{
$this->registerPolicies();

Passport::routes();
}
}

最后,将配置文件 config/auth.php 中授权看守器 guards 的 api 的 driver 选项改为 passport。此调整会让你的应用程序在在验证传入的 API 的请求时使用 Passport 的 TokenGuard 来处理:

1
2
3
4
5
6
7
8
9
10
11
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],

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

使用 Passport 的 Vue 组件

composer require laravel/ui –dev
php artisan ui vue –auth
php artisan vendor:publish –tag=passport-components
npm i
npm run dev

被发布的组件将会被放到 resources/js/components 目录下。当组件被发布后,你应该在你的 resources/js/app.js 文件中注册它们:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Vue.component(
'passport-clients',
require('./components/passport/Clients.vue').default
);

Vue.component(
'passport-authorized-clients',
require('./components/passport/AuthorizedClients.vue').default
);

Vue.component(
'passport-personal-access-tokens',
require('./components/passport/PersonalAccessTokens.vue').default
);

在注册了组件后,请确保运行 npm run dev 来重新编译你的资源。 当你重编译你的资源后,你可以将组件放到你应用的模板home.blade.php中以开始创建客户端和个人访问令牌:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@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

You are logged in!
</div>
</div>
<div id="app">
<passport-clients></passport-clients>
<passport-authorized-clients></passport-authorized-clients>
<passport-personal-access-tokens></passport-personal-access-tokens>
</div>
</div>
</div>
</div>
@endsection

可以在 AuthServiceProvider 的 boot 方法中使用 Passport::tokensCan 方法来定义 API 的作用域。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
// 'App\Model' => 'App\Policies\ModelPolicy',
];

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

Passport::routes();
Passport::tokensCan([
'users' => 'Place users',
'devices' => 'Check device status',
]);
Passport::setDefaultScope([
'users',
]);
}
}

编辑routes/api.php设置路由

1
2
3
4
5
6
7
8
9
10
11
12
Route::domain('api.laravel.test')->group(function () {
Route::middleware(['auth:api'])->group(function () {
Route::get('/user', function (Request $request) {
return $request->user();
});
Route::get('/device', function (Request $request) {
if ($request->user()->tokenCan('devices')) {
return ['device' => 1];
}
});
});
});

访问https://laravel.test,注册一个用户登录后,创建一个OAuth Clients。

使用postman等客户端获取accesstoken

通常,如果要在 JavaScript 应用程序中使用 API ,需要手动向应用程序发送访问令牌,并将其传递给应用程序。但是, Passport 有一个可以处理这个问题的中间件。将 CreateFreshApiToken 中间件添加到 app/Http/Kernel.php 文件中的 web 中间件组就可以了:

1
2
3
4
'web' => [
// 确保在您的中间件堆栈中 CreateFreshApiToken 中间件之前列出了 EncryptCookies 中间件。
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],

增加中间件允许跨域访问

php artisan make:middleware EnableCrossRequestMiddleware

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
/**
* 跨域设置
*/

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Response;

class EnableCrossRequestMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);

$origin = $request->server('HTTP_ORIGIN') ? $request->server('HTTP_ORIGIN') : '';
$allow_origin = [
'http://localhost',
];

if (in_array($origin, $allow_origin)) {

$response->header('Access-Control-Allow-Origin', $origin);
$response->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Cookie, X-CSRF-TOKEN, Accept, Authorization, X-XSRF-TOKEN');
$response->header('Access-Control-Expose-Headers', 'Authorization, authenticated');
$response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS');
$response->header('Access-Control-Allow-Credentials', 'true');
}
return $response;
}
}

在 app/Http/Kernal.php 文件中将其注册为全局中间件

1
2
3
protected $middleware = [
\App\Http\Middleware\EnableCrossRequestMiddleware::class, // 添加这一行将其注册为全局中间件
];

编写js通过API访问数据(第一次需指定Bearer 数据,后续就不需要了)

1
2
3
4
5
6
axios({
method: 'get',
url: 'https://api.laravel.test/api/user',
}).then(res => {
console.log(res);
});
文章作者: pengweifu
文章链接: https://www.pengwf.com/2019/12/25/web/PHP-Laravel/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 麦子的博客
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论