You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel中通过Socialite登录后无需用户名密码生成Passport access_token

解决Socialite登录后生成Passport Access Token的安全问题

你的问题核心是用默认密码通过Password Grant生成token存在严重安全隐患——一旦这个默认密码泄露,攻击者就能轻易登录任意社交登录用户的账号。下面是更安全且高效的解决方案:

直接生成Personal Access Token替代Password Grant

Laravel Passport提供了直接通过用户模型生成个人访问令牌的方法,完全不需要依赖用户密码,既规避了默认密码的风险,还省去了额外的HTTP请求开销。

步骤1:确认User模型的Passport依赖

首先检查你的User模型是否已经引入Passport的HasApiTokens trait(通常安装Passport时会自动添加,但建议确认):

use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;

    // ... 其他模型代码
}

步骤2:替换生成token的逻辑

把原来通过HTTP请求调用/oauth/token的不安全代码,替换成直接生成令牌的代码:

修改前的风险代码

$http = new Client;
$response = $http->post(config('app.url').'/oauth/token', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => '2',
        'client_secret' => 'oBKWxgF2fDvrxwA05ciapwy4JYKaHxzhGzr6D24X',
        'username' => $email,
        'password' => 'gebdandi',
        'scope' => '',
    ],
]);
$body = json_decode((string) $response->getBody(), true);
$accessToken = $body['access_token'];

修改后的安全代码

// 直接为当前用户创建个人访问令牌
$tokenResult = $user->createToken('Social Login Access Token');
$accessToken = $tokenResult->accessToken;

// 可选:自定义令牌过期时间(例如设置为7天)
$tokenResult->token->expires_at = \Carbon\Carbon::now()->addDays(7);
$tokenResult->token->save();

完整修改后的代码

try {
    $serviceUser = Socialite::driver($service)->stateless()->user();
} catch (\Exception $e) {
    return redirect(config('app.client_url').'/auth/social-callback?error=Unable to login using '.$service.'. Please try again'.'&origin=login');
}
$email = $serviceUser->getEmail();
$name = $serviceUser->getName();
$user = $this->getExistingUser($serviceUser, $email, $service);
$newUser = false;
if (!$user) {
    $newUser = true;
    $user = new User;
    $user->name = $name;
    $user->email = $email;
    $user->username = Str::random(10);
    if ($service === 'facebook') {
        $user->image = $serviceUser->avatar;
    }
    $user->verify = true;
    $user->save();
}
if ($this->needsToCreateSocial($user, $service)) {
    Social::create([
        'user_id' => $user->id,
        'social_id' => $serviceUser->getId(),
        'service' => $service
    ]);
}

// 生成安全的Access Token
$tokenResult = $user->createToken('Social Login Access Token');
$accessToken = $tokenResult->accessToken;
// 可选设置过期时间
$tokenResult->token->expires_at = \Carbon\Carbon::now()->addDays(7);
$tokenResult->token->save();

return redirect(config('app.client_url').'/social-callback?token='.$accessToken.'&origin='.($newUser ? 'register' : 'login'));

方案优势说明

  • 安全性拉满:不再依赖任何密码(包括默认密码),直接通过用户模型生成令牌,彻底消除密码泄露的风险。
  • 性能更优:省去了向/oauth/token发送HTTP请求的步骤,减少服务器内部调用开销。
  • 灵活性高:可以自定义令牌名称、设置过期时间,后续还能通过Passport的API管理这些令牌(比如撤销特定令牌)。

内容的提问来源于stack exchange,提问作者sid heart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:05:20