在 Laravel 中使用 Passport 配置 OAuth 2.1

在 Laravel 中使用 Passport 配置 OAuth 2.1 需要结合其安全规范(如强制 PKCE、废除隐式授权等)。以下是完整配置指南:


1. 安装 Laravel Passport

composer require laravel/passport
php artisan passport:install  # 生成加密密钥和客户端表
php artisan migrate           # 创建 oauth_* 表

2. 基础配置

注册服务提供者

app/Providers/AuthServiceProvider.php 中:

use Laravel\Passport\Passport;

public function boot() {
    Passport::routes(); // 注册 OAuth2 路由
    Passport::hashClientSecrets(); // 加密客户端密钥(OAuth 2.1 推荐)
    Passport::enableAuthorizationCodeGrant(); // 仅启用授权码模式
    Passport::disableImplicitGrant(); // 禁用隐式授权(OAuth 2.1 废除)
    Passport::disablePasswordGrant(); // 禁用密码模式(OAuth 2.1 废除)
}
用户模型配置

app/Models/User.php 中:

use Laravel\Passport\HasApiTokens;

class User extends Authenticatable {
    use HasApiTokens, Notifiable;
}
Auth 配置

config/auth.php 中:

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

3. 强制 PKCE(OAuth 2.1 核心)

Passport 默认支持 PKCE,但需确保客户端正确使用。

创建 PKCE 客户端
php artisan passport:client --public --redirect_uri="https://your-app/callback"

或通过代码创建:

Passport::client()->forceFill([
    'user_id' => null,
    'name' => 'PKCE Client',
    'secret' => null, // 公共客户端不存储密钥
    'redirect' => 'https://your-app/callback',
    'personal_access_client' => false,
    'password_client' => false,
    'revoked' => false,
    'public_client' => true, // 标记为公共客户端(如 SPA)
])->save();
前端 PKCE 流程示例(SPA)
  1. 生成 code_verifiercode_challenge
// 使用 crypto-js 或类似库
const codeVerifier = generateRandomString(128);
const codeChallenge = base64UrlEncode(sha256(codeVerifier));
  1. 跳转授权页
GET /oauth/authorize?
    response_type=code&
    client_id=your-client-id&
    redirect_uri=https://your-app/callback&
    scope=user-info&
    code_challenge=your-code-challenge&
    code_challenge_method=S256
  1. code_verifier 交换令牌
POST /oauth/token
Content-Type: application/json

{
    "grant_type": "authorization_code",
    "client_id": "your-client-id",
    "redirect_uri": "https://your-app/callback",
    "code": "authorization-code-from-callback",
    "code_verifier": "your-original-code-verifier"
}

4. 令牌生命周期管理(OAuth 2.1 改进)

短期访问令牌 + 刷新令牌

AppServiceProvider 中配置:

Passport::tokensExpireIn(now()->addHours(1)); // 访问令牌 1 小时过期
Passport::refreshTokensExpireIn(now()->addDays(30)); // 刷新令牌 30 天过期
刷新令牌绑定

确保刷新令牌仅能由原客户端使用:

// 在 AuthServiceProvider 中
Passport::refreshTokensBindToClient();

5. 安全增强配置

强制 HTTPS

AppServiceProvider 中:

URL::forceScheme('https'); // OAuth 2.1 要求所有通信加密
令牌作用域限制

颁发令牌时限制最小权限:

$token = $user->createToken('token-name', ['read:user']); // 仅允许读取用户信息
撤销令牌
$user->tokens()->where('id', $tokenId)->delete(); // 主动撤销令牌

6. 完整 OAuth 2.1 端点列表

端点路径用途
授权页/oauth/authorize获取授权码(强制 PKCE)
令牌颁发/oauth/token用授权码/刷新令牌交换新令牌
令牌撤销/oauth/token/revoke主动撤销令牌
客户端管理/oauth/clients管理 OAuth 客户端(需认证)

7. 测试验证

使用 Postman 测试 PKCE 流程
  1. 设置环境变量:
    • code_verifier = 随机字符串
    • code_challenge = BASE64URL-ENCODE(SHA256(code_verifier))
  2. 发送授权请求:
    GET /oauth/authorize?response_type=code&client_id=1&redirect_uri=https://your-app/callback&code_challenge=...
    
  3. 用返回的 code 交换令牌:
    POST /oauth/token
    Body: { "code_verifier": "...", "code": "..." }
    

8. 常见问题

错误:invalid_grant
  • 确保 code_verifier 与授权请求的 code_challenge 匹配。
  • 检查 redirect_uri 完全一致(包括末尾斜杠)。
错误:unsupported_grant_type
  • 确认已禁用密码和隐式授权:
    Passport::disablePasswordGrant();
    Passport::disableImplicitGrant();
    

总结

通过以上配置,你的 Laravel Passport 将符合 OAuth 2.1 规范:

  1. 强制 PKCE 防护授权码劫持。
  2. 废除隐式/密码模式‌ 消除已知风险。
  3. 短期令牌 + 绑定刷新令牌‌ 增强安全性。
  4. 强制‌HTTPS 保障传输安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值