Laravel Passport 如何免密码自定义登录用户并生成认证令牌
解决Laravel Passport编程式免密码登录并生成令牌的问题
核心问题排查
你遇到auth()->login后当前用户为null的情况,大概率是这几个原因:
- 传入
login方法的不是有效Eloquent用户实例 - 使用了不支持session登录的认证Guard(比如Passport的
apiGuard,它是无状态的token驱动) - 在无session的环境(如API请求)中调用了依赖session的
login方法
分步解决方案
1. 确保正确加载用户实例
先检查你的LoadByEmail方法,必须返回完整的Eloquent模型实例,不能是数组或null:
// User模型中的方法 public static function LoadByEmail($email) { return self::where('email', $email)->first(); }
调用后一定要先判断用户是否存在,避免后续操作处理空值。
2. 正确执行用户登录(按需选择)
- 如果是Web环境(需要维持session登录状态):
使用默认的webGuard执行登录,它是session驱动的,支持login方法:$user = User::LoadByEmail($request->email); if ($user) { // 执行登录 auth('web')->login($user); // 获取当前用户 $currentUser = auth('web')->user(); } - 如果是API环境(不需要session,直接生成令牌):
不需要调用auth()->login,直接为用户生成Passport个人访问令牌即可,这才是API场景下的正确方式:$user = User::LoadByEmail($request->email); if (!$user) { return response()->json(['message' => '用户不存在'], 404); } // 生成个人访问令牌 $token = $user->createToken('ProgrammaticLoginToken')->accessToken;
3. 完整示例代码
AuthController中的实现:
use Illuminate\Http\Request; use App\Models\User; class AuthController extends Controller { public function programmaticLogin(Request $request) { $request->validate(['email' => 'required|email']); $user = User::LoadByEmail($request->email); if (!$user) { return response()->json(['message' => '用户不存在'], 404); } // 可选:Web环境下维持session登录 if (request()->is('web/*')) { auth()->login($user); } // 生成Passport令牌 $tokenResult = $user->createToken('ProgrammaticLogin'); $token = $tokenResult->accessToken; return response()->json([ 'user' => $user, 'access_token' => $token, 'token_type' => 'Bearer', 'expires_at' => $tokenResult->token->expires_at ]); } }
必要前置检查
- 确保User模型引入了Passport的
HasApiTokenstrait:use Laravel\Passport\HasApiTokens; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use HasApiTokens, Notifiable; // ... } - 已经完成Laravel Passport的初始化配置(运行过
php artisan passport:install,配置了Auth Guard等)
内容的提问来源于stack exchange,提问作者Luca Calabrese
相关产品推荐
相关产品推荐

