Laravel如何使用Passport OAuth 进行用户登录认证
Laravel Passport 可以在几分钟之内为你的应用程序提供完整的 OAuth2 服务端实现。Passport 是基于由 Andy Millington 和 Simon Hamp 维护的 League OAuth2 server 建立的。
安装
在开始使用之前,使用 Composer 包管理器安装 Passport:
composer require laravel/passport
Passport 的 服务提供器 注册了自己的数据库迁移脚本目录, 所以你应该在安装软件包完成后迁移你自己的数据库。 Passport 的迁移脚本将为你的应用创建用于存储 OAuth2 客户端和访问令牌的数据表:
php artisan migrate
接下来,你需要执行 Artisan 命令 passport:install。这个命令将会创建一个用于生成安全访问令牌的加密秘钥。另外,这个命令也将创建用于生成访问令牌的 “个人访问” 客户端和 “密码授权” 客户端 :
php artisan passport:install
注意这里有一个坑
在进行数据库迁移的时候有时候会提示如下错误信息
Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes
这是数据库不支持长字节,默认情况下,laravel 使用 utf8mb4 编码。如果你是在版本低于 5.7.7 的 MySQL 或者版本低于 10.2.2 的 MariaDB 上创建索引,那你就需要手动配置数据库迁移的默认字符串长度。也就是说,你可以通过在 App\Providers\AppServiceProvider 类的 boot 方法中调用 Schema::defaultStringLength 方法来配置默认字符串长度:
use Illuminate\Support\Facades\Schema;
/**
* 引导任何应用程序「全局配置」
*
* @return void
*/
public function boot()
{
Schema::defaultStringLength(191);
}
执行完passport:install后会生成两个客户端秘钥
Client ID: 1
Client Secret: AwDMcCs65rXkzF80wPaINx5fkoXEfa8lcuuPEvQK
Password grant client created successfully.
Client ID: 2
Client Secret: KLlLijWk3hX2Ntfzo2iFPgwT4GyITpBjEuDozp5H
配置
在执行 passport:install 命令后, 添加 laravel\Passport\HasApiTokens trait 到你的 App\Models\User 模型中。 这个 trait 会提供一些帮助方法用于检查已认证用户的令牌和权限范围。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
然后,在你应用的配置文件 config/auth.php 中, 将 api 的授权看守器 guards 的 driver 参数的值设置为 passport。此调整会让你的应用程序使用 Passport 的 TokenGuard 鉴权 API 接口请求:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
默认情况下,Passport 会发行生命周期一年的长期 token 。如果要配置更长或更短生命周期的 token,可以使用 tokensExpireIn 、refreshTokensExpireIn 和 personalAccessTokensExpireIn 方法。这些方法需要在应用的 App\Providers\AuthServiceProvider 的 boot 方法中调用:
/**
* 注册身份验证/授权服务
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::tokensExpireIn(now()->addDays(15));
Passport::refreshTokensExpireIn(now()->addDays(30));
Passport::personalAccessTokensExpireIn(now()->addMonths(6));
}
发放access_token
场景一: 我的用户,在别的网站想用我的账号直接登录,参考微信登录。那么第三方网站就要对接过来,用户选择第三方登录,跳转到我的页面,询问用户是否允许,用户允许以后我会带一个code回去,第三方网站用这个code请求access_token
请求令牌
use Illuminate\Http\Request;
use Illuminate\Support\Str;
Route::get('/redirect', function (Request $request) {
$request->session()->put('state', $state = Str::random(40));
$query = http_build_query([
'client_id' => 'client-id',
'redirect_uri' => 'http://third-party-app.com/callback',
'response_type' => 'code',
'scope' => '',
'state' => $state,
]);
return redirect('http://passport-app.test/oauth/authorize?'.$query);
});
用户允许以后拿到code换token
如果用户授权了访问,他们会被重定向到业务服务端。(首先,业务端服务需要检查 state 参数是否和重定向之前存储的值一致,这一步骤可以根据自身需求而定)。 如果 state 参数的值正确,业务端服务器需要对你的应用发起获取 access token 的 POST 请求。 请求需要携带有授权码,授权码就是之前用户授权后由你的应用服务器生成的码:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
Route::get('/callback', function (Request $request) {
$state = $request->session()->pull('state');
throw_unless(
strlen($state) > 0 && $state === $request->state,
InvalidArgumentException::class
);
$response = Http::asForm()->post('http://passport-app.test/oauth/token', [
'grant_type' => 'authorization_code',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'redirect_uri' => 'http://third-party-app.com/callback',
'code' => $request->code,
]);
return $response->json();
});
token如果过期了,可以刷新token
use Illuminate\Support\Facades\Http;
$response = Http::asForm()->post('http://passport-app.test/oauth/token', [
'grant_type' => 'refresh_token',
'refresh_token' => 'the-refresh-token',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'scope' => '',
]);
return $response->json();
场景二:这个主要是用于自己本身的项目,用户通过app等输入账号和密码,我用账号密码校验正确了就发送access_token
use Illuminate\Support\Facades\Http;
$response = Http::asForm()->post('http://passport-app.test/oauth/token', [
'grant_type' => 'password',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'username' => 'taylor@laravel.com',
'password' => 'my-password',
'scope' => '',
]);
return $response->json();
这种跟第一种差不多,就是省去了code 直接发放,主要用于JavaScript 或移动应用中客户端登录认证信息不能保存时
在你使用密码授权方式发布令牌前,你需要先创建密码授权方式的客户端。你可以通过 Artisan 命令 passport:client , 并加上 --password 参数来创建这样的客户端。
如果你已经运行过 passport:install 命令,则不需要再运行下面的命令,因为他已经帮你默认创建两个了:
php artisan passport:client --password
使用
我们希望当用户注册成功之后返回token给app
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Http;
class RegisterController extends Controller
{
private $http;
public function __construct(Http $http)
{
$this->http = $http;
}
public function register(Request $request)
{
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password)
]);
$response = $this->http->post('http://passport-app.test/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'username' => $user->email,
'password' => $request->password,
'scope' => '*',
],
]);
$token = json_decode((string) $response->getBody(), true);
return response()->json([
'token'=> $token
],200);
}
}
以上这篇laravel如何使用Passport OAuth 进行用户登录认证就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持芦苇派。
原创文章,作者:ECHO陈文,如若转载,请注明出处:https://www.luweipai.cn/php/1670141287/