- 准备两个服务器,一个模拟第三方服务器,一个模拟授权服务器
- 授权服务器(微信)(mushishi.com)
通过 Composer 包管理器安装 Passport:
其中laravel/passport 提供 OAuth 认证服务
composer require laravel/passport
创建存储客户端和令牌的数据表:
php artisan migrate
接下来,运行 passport:install 命令来创建生成安全访问令牌时所需的加密密钥,同时,这条命令也会创建用于生成访问令牌的「个人访问」客户端(Personal Access Client)和「密码授权」客户端(Password Grant Client):
php artisan passport:install
// 或者使用
php artisan passport:keys // 加密生成的 access_token
php artisan passport:client // 创建自定义客户端,生成client ID 和 client secret
PS:生成的access_token位置——storage/oauth-private.key
上面命令执行后,请将 Laravel\Passport\HasApiTokens Trait 添加到 App\User 模型中,这个 Trait 会给你的模型提供一些辅助函数,用于检查已认证用户的令牌和使用范围:
use HasApiTokens, Notifiable;
接下来,在 AuthServiceProvider 的 boot 方法中调用 Passport::routes 注册令牌相关的路由
Passport::routes();
// Laravel中默认refresh_token 过期时间等于access_token 过期时间,
// refresh_token 过期时间要大于access_token 过期时间,因为只有这样,当access_token过期后,由于refresh_token 没过期,可以通过refresh_token 去刷新access_token
Passport::tokensExpireIn(now()->addDays(15)); // access_token 过期时间
Passport::refreshTokensExpireIn(now()->addDays(60)); // refresh_token 过期时间
最后,将配置文件 config/auth.php 中授权看守器 guards 的 api 的 driver 选项改为 passport。此调整会让你的应用程序在在验证传入的 API 的请求时使用 Passport 的 TokenGuard 来处理:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
- 第三方服务器(B站)(mushi.com)
第一步,A 网站提供一个链接,用户点击后就会跳转到 B 网站,授权用户数据给 A 网站使用。下面就是 A 网站跳转 B 网站的一个示意链接。
https://b.com/oauth/authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read
代码实现:
(1)路由
// 登录页面
Route::view('/login', 'login');
(2)视图resources/views/login.blade.php
// 跳转到/mushishi/login,根据示意链接,发送链接
<a href="/mushishi/login">微信登陆</a>
(3)路由
$clientId = 1; // 授权服务器生成的client_id,要与数据库一致
$clientSecret = 'T51YiRBezu2QZzmodyTGPKdNJZ4MpeiGPv5PmjiJ'; // 授权服务器生成的client_secret,要与数据库一致
// 前面点击微信登陆后进入此处
Route::get('/mushishi/login',
function (\Illuminate\Http\Request $request) use ($clientId) {
// state用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击,可设置为简单的随机数加session进行校验
$request->session()->put('state', $state = Str::random(40));
$query =