OAuth2.0介绍
http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
安装参考文档
本案例使用框架版本为5.5
https://learnku.com/docs/laravel/5.5/passport/1309#08129f
https://my.oschina.net/u/2400083/blog/1036519
composer require paragonie/random_compat=~2.0(如果出现包冲突)
composer require laravel/passport=~4.0
在 AuthServiceProvider
的 boot
方法中调用 Passport::routes
函数。这个函数会注册发出访问令牌并撤销访问令牌、客户端和个人访问令牌所必需的路由
授权模式使用演示
客户端模式
客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向”服务提供商”进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求”服务提供商”提供服务,其实不存在授权问题。
看一下storage目录是否有key ,没有key 执行 php artisan passport:keys
客户端凭据授权适用于机器到机器的认证。例如,你可以在通过 API 执行维护任务中使用此授权。要使用这种授权,你首先需要在 app/Http/Kernel.php
的 $routeMiddleware
变量中添加新的中间件:
use Laravel\Passport\Http\Middleware\CheckClientCredentials::class;
protected $routeMiddleware = [
'client' => CheckClientCredentials::class,
];
然后在路由上追加这个中间件:
Route::get('/orders', function(Request $request) {
...
})->middleware('client');
个人访问令牌
如果用户要在不经过典型的授权码重定向流的情况下向自己发出访问令牌,可以允许用户通过应用程序的用户界面对自己发出令牌,用户可以因此顺便测试你的 API,或者也可以将其作为一种更简单的发布访问令牌的方式。
{note} 个人访问令牌是永久有效的,就算使用了
tokensExpireIn
和refreshTokensExpireIn
方法也不会修改它的生命周期。token设置有效期解决方案 https://github.com/laravel/passport/issues/162
token设置有效期代码示例
<?php
namespace App\Providers;
use DateInterval;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Laravel\Passport\Bridge\PersonalAccessGrant;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*/
public function boot()
{
$this->registerPolicies();
//设置个人token失效时间为7天
$authorizarionServer = app()->make(\League\OAuth2\Server\AuthorizationServer::class);
$authorizarionServer->enableGrantType(
new PersonalAccessGrant(),
new DateInterval('PT7D')
);
}
}
实现单一客户端登录(只有一个token生效)
https://segmentfault.com/q/1010000008481512/a-1020000008481698
https://learnku.com/laravel/t/16144
自定义认证看守器(guard)
场景:
需要非用户模型的表进行认证。比如物联网开发中,需要对设备进行认证为例。
安装步骤和配置步骤不变,请参考laravel passport文档
设备表迁移文件
Schema::create('devices', function(Blueprint $table)
{
$table->increments('id');
$table->string('mac_address', 17)->default('')->comment('设备mac地址')->index('mac_address','mac_indx');
$table->string('alias', 20)->default('')->comment('设备别名');
$table->timestamps();
});
DB::statement("ALTER TABLE devices comment '设备表'");
模型配置
//设备模型需要继承用户认证模型 Illuminate\Foundation\Auth\User
// 引用passport 的 HasApiTokens trait
<?php
namespace App\Models;
use Laravel\Passport\HasApiTokens;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Device extends Authenticatable
{
use HasApiTokens;
protected $table = 'devices';
protected $fillable = ['mac_address', 'alias'];
protected $dates = [];
protected $casts = [];
protected $appends = [];
protected $hidden = [
'pivot',
];
}
config/auth.php 看守器
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
//增加设备看守器
'device' => [
'driver' => 'passport',
'provider' => 'devices',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
//提供者增加设备模型
'devices' => [
'driver' => 'eloquent',
'model' => App\Models\Device::class,
],
],
app/Providers/AuthServiceProvider.php 服务提供者作用域配置
public function boot()
{
$this->registerPolicies();
Passport::routes();
Passport::loadKeysFrom('');
Passport::personalAccessTokensExpireIn(now()->addMonths(6));
Passport::tokensCan([
'api' => 'api',
]);
}
作用域中间件配置
protected $routeMiddleware = [
...
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
];
路由和控制器测试代码
Route::prefix('test')->group(function () {
Route::post('login', [TestController::class,'login']);
Route::get('show', [TestController::class,'show'])->middleware(['auth:device','scope:api']);
});
<?php
namespace App\Http\Controllers;
use App\Models\Device;
use App\Models\User;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function login(Request $request)
{
$guard_model = Device::find(1);
$token = $guard_model->createToken('device', ['api'])->accessToken;
return response()->json([
'token' => $token
]);
}
public function show(Request $request)
{
return response()->json($request->user('device'));
}
}
测试结果使用device guard看守器成功获取模型