如何在Laravel框架中实现Plaid身份验证产品?
在Laravel中通过Plaid模板实现身份验证的分步指南
1. 复用现有SDK配置
既然你已经用github.com/TomorrowIdeas/plaid-sdk-php实现过Investments产品,先确认.env里的Plaid密钥配置完整:
PLAID_CLIENT_ID=你的客户端ID PLAID_SECRET=你的密钥 PLAID_ENV=sandbox # 生产环境改为production/development
如果之前没发布过SDK配置,可运行php artisan vendor:publish --provider="TomorrowIdeas\Plaid\PlaidServiceProvider"生成config/plaid.php,确保配置和.env对应。
2. 后端生成Link Token
身份验证的核心是通过Plaid Link获取用户授权,首先需要后端生成前端初始化Link所需的link_token。
创建/更新PlaidController,添加生成Link Token的方法:
<?php namespace App\Http\Controllers; use TomorrowIdeas\Plaid\Plaid; use Illuminate\Http\Request; class PlaidController extends Controller { protected $plaid; public function __construct(Plaid $plaid) { $this->plaid = $plaid; } public function createLinkToken(Request $request) { // 传入当前登录用户的唯一标识,用于Plaid关联用户 $userId = strval(auth()->user()->id); $response = $this->plaid->linkTokens->create([ 'user' => ['client_user_id' => $userId], 'client_name' => '你的应用名称', 'products' => ['auth'], // 指定启用身份验证产品 'country_codes' => ['US'], // 根据用户地区调整,如GB、CA 'language' => 'en' // 支持多语言,如zh ]); return response()->json(['link_token' => $response->link_token]); } }
在routes/api.php添加路由:
Route::post('/plaid/create-link-token', [PlaidController::class, 'createLinkToken'])->middleware('auth');
3. 前端集成Plaid Link模板
前端加载Plaid官方Link脚本,通过后端返回的link_token初始化弹窗,引导用户完成身份验证。
创建Blade视图(如resources/views/plaid/auth.blade.php):
<div id="plaid-link-trigger" class="btn btn-primary">开始身份验证</div> <script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script> <script> async function fetchLinkToken() { const res = await fetch('/api/plaid/create-link-token', { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content, 'Content-Type': 'application/json' } }); return (await res.json()).link_token; } async function initPlaidLink() { const linkToken = await fetchLinkToken(); const handler = Plaid.create({ token: linkToken, onSuccess: async (publicToken, metadata) => { // 将临时public_token传给后端交换为长期access_token const res = await fetch('/api/plaid/exchange-token', { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content, 'Content-Type': 'application/json' }, body: JSON.stringify({ public_token: publicToken }) }); const result = await res.json(); // 处理验证成功逻辑,如跳转、提示用户 console.log('身份验证完成,Access Token:', result.access_token); alert('身份验证成功'); }, onExit: (error) => { if (error) { console.error('验证失败:', error); alert('验证出错:' + error.message); } } }); // 绑定触发按钮 document.getElementById('plaid-link-trigger').addEventListener('click', () => handler.open()); } document.addEventListener('DOMContentLoaded', initPlaidLink); </script>
4. 后端交换Public Token并获取验证数据
前端拿到public_token后,后端需要将其交换为长期有效的access_token,同时获取用户的身份验证详情(如账户路由号、所有者信息)。
在PlaidController添加交换方法:
public function exchangePublicToken(Request $request) { $request->validate(['public_token' => 'required|string']); // 交换token $exchangeRes = $this->plaid->itemPublicToken->exchange($request->public_token); $accessToken = $exchangeRes->access_token; $itemId = $exchangeRes->item_id; // 获取身份验证核心数据 $authRes = $this->plaid->auth->get($accessToken); // 将数据存入数据库,关联到当前用户 auth()->user()->plaidItems()->create([ 'item_id' => $itemId, 'access_token' => $accessToken, 'account_details' => $authRes->accounts, 'auth_numbers' => $authRes->numbers ]); return response()->json([ 'access_token' => $accessToken, 'item_id' => $itemId, 'auth_info' => $authRes->numbers ]); }
添加对应路由到routes/api.php:
Route::post('/plaid/exchange-token', [PlaidController::class, 'exchangePublicToken'])->middleware('auth');
5. 可选:身份信息校验
如果需要验证用户提交的信息(如姓名、地址)与Plaid返回的一致,可调用identity接口获取所有者信息并对比:
// 在exchangePublicToken方法中添加 $identityRes = $this->plaid->identity->get($accessToken); $ownerInfo = $identityRes->accounts[0]->owners[0]; // 对比用户姓名 if ($ownerInfo->names[0] !== auth()->user()->name) { return response()->json(['error' => '身份信息不匹配'], 400); }
关键注意事项
- 确保Plaid Dashboard中已启用
Auth产品(Products选项卡开启) - 沙箱环境用Plaid测试账号(如
user_good/pass_good)验证流程 - 生产环境需通过Plaid合规审核,确保数据处理符合要求
access_token仅在后端存储使用,禁止前端暴露
内容的提问来源于stack exchange,提问作者anon
相关产品推荐
相关产品推荐

