在 Laravel 12 中实现 OAuth 2.1,推荐使用 Laravel Passport(官方 OAuth2 服务器包)或 Laravel Sanctum(轻量级 API 认证)。由于 OAuth 2.1 主要强化了安全性(如强制 PKCE、废除隐式授权等),我们需要结合最新规范进行配置。
方案 1:使用 Laravel Passport(完整 OAuth2 服务器)
Passport 是 Laravel 官方提供的 OAuth2 服务器实现,支持 OAuth 2.1 的核心特性(如 PKCE)。
1. 安装 Laravel Passport
composer require laravel/passport
php artisan passport:install # 生成加密密钥和客户端密钥
2. 配置 Passport
在 app/Models/User.php
中启用 HasApiTokens
:
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable {
use HasApiTokens, Notifiable;
}
在 app/Providers/AuthServiceProvider.php
中注册 Passport 路由:
use Laravel\Passport\Passport;
public function boot() {
Passport::routes(); // 注册 OAuth2 路由
Passport::hashClientSecrets(); // 加密客户端密钥(OAuth 2.1 推荐)
Passport::enableImplicitGrant(); // 默认禁用隐式授权(OAuth 2.1 废除)
}
3. 配置 OAuth 2.1 客户端(强制 PKCE)
创建客户端时启用 PKCE:
php artisan passport:client --public --redirect_uri="http://your-app/callback"
或通过代码创建:
$client = Passport::client()->forceFill([
'user_id' => null,
'name' => 'PKCE Client',
'secret' => null, // 公共客户端不存储密钥(OAuth 2.1 要求)
'redirect' => 'http://your-app/callback',
'personal_access_client' => false,
'password_client' => false,
'revoked' => false,
'public_client' => true, // 标记为公共客户端(如 SPA 或移动端)
])->save();
4. 实现授权码流程(PKCE 强制)
前端(SPA 或移动端)
- 生成
code_verifier
和code_challenge
(PKCE 要求):
// 使用 crypto-js 或类似库
const codeVerifier = generateRandomString(128);
const codeChallenge = base64UrlEncode(sha256(codeVerifier));
- 跳转到授权页面(携带
code_challenge
):
GET /oauth/authorize?
response_type=code&
client_id=your-client-id&
redirect_uri=http://your-app/callback&
scope=user-info&
code_challenge=your-code-challenge&
code_challenge_method=S256
-
用户授权后,后端返回
authorization_code
到回调地址。 -
用
code_verifier
交换令牌:
POST /oauth/token
Content-Type: application/json
{
"grant_type": "authorization_code",
"client_id": "your-client-id",
"redirect_uri": "http://your-app/callback",
"code": "authorization-code-from-callback",
"code_verifier": "your-original-code-verifier"
}
后端验证(自动处理 PKCE)
Passport 默认支持 PKCE,无需额外代码。
方案 2:使用 Laravel Sanctum(轻量级 API 认证)
如果不需要完整的 OAuth2 服务器,Sanctum 提供简单的 API 令牌认证(类似 OAuth2 的客户端凭证模式)。
1. 安装 Sanctum
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
2. 配置 Sanctum
在 app/Models/User.php
中启用 HasApiTokens
:
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable {
use HasApiTokens, Notifiable;
}
3. 颁发访问令牌
$user = User::find(1);
$token = $user->createToken('token-name', ['scope:user-info'])->plainTextToken;
4. 验证令牌
Sanctum 会自动验证 Authorization: Bearer <token>
请求头。
OAuth 2.1 关键配置总结
需求 | Laravel Passport 方案 | Laravel Sanctum 方案 |
---|---|---|
PKCE 强制 | 默认支持 | 不适用(无授权码流程) |
废除隐式授权 | 默认禁用 | 不适用 |
废除密码模式 | 需手动禁用 | 不适用 |
客户端认证 | 支持(client_secret ) | 仅简单令牌认证 |
适用场景 | 第三方应用授权(如 GitHub) | 第一方 SPA / 移动端 API |
最佳实践建议
- 优先使用 Passport:如果需要完整的 OAuth 2.1 服务器(如第三方登录)。
- 禁用不安全模式:
// 在 AuthServiceProvider 中禁用密码模式 Passport::disablePasswordGrant();
- 强制 HTTPS:OAuth 2.1 要求所有通信加密。
- 限制令牌范围:
$token = $user->createToken('token-name', ['read:user']); // 最小权限原则
完整示例代码
通过以上步骤,你可以在 Laravel 12 中安全地实现 OAuth 2.1 规范。