Laravel中使用Cookie实现前端认证的问题排查
问题场景
我在Laravel中实现了登录控制器,生成并返回Cookie:
public function login(Request $request) { try { $validatedData = $request->validate([ 'email' => 'required|email', 'password' => 'required|string|min:6', ]); $user = User::where('email', $validatedData['email'])->first(); if (!$user || !Hash::check($validatedData['password'], $user->password)) { throw ValidationException::withMessages([ 'email' => ['Invalid credentials'], ]); } $token = $user->createToken('authToken')->plainTextToken; } catch (ValidationException $e) { return response()->json(['errors' => $e->errors()], 422); } $cookie = cookie('auth_token', $token, 60 * 24 * 7); return response()->json(['user' => $user, 'token' => $token], 201)->withCookie($cookie); }
在web.php中配置了使用自定义中间件EnsureTokenIsValid的路由组:
Route::middleware([EnsureTokenIsValid::class])->group(function () { Route::get('/', function () { return view('welcome'); }); });
自定义中间件代码:
public function handle(Request $request, Closure $next): Response { if ($request->hasCookie('auth_token')) { $token = $request->cookie('auth_token'); error_log($token); } if (!$request->hasCookie('auth_token')) { error_log("No cookie"); } return $next($request); }
登录成功后浏览器已正确设置Cookie,但请求中未携带该Cookie,终端始终输出:
WARN No cookie.
问题原因及解决方法
一、Cookie未被携带的原因及修复
- SameSite属性与跨域/请求类型不匹配
Laravel默认Cookie的SameSite属性为lax,若登录请求是AJAX跨域请求,或非GET类型的同域请求,浏览器可能会拦截Cookie携带。需显式配置Cookie的SameSite、Secure、HttpOnly属性:
$cookie = cookie() ->make('auth_token', $token, 60 * 24 * 7) ->sameSite('none') // 根据场景选择none/lax/strict ->secure(true) // 生产环境建议开启,需HTTPS支持 ->httpOnly(true); // 防止XSS攻击获取Cookie
同域场景下,若为POST请求需携带Cookie,同样需要调整SameSite为none并开启secure(HTTPS环境)。
中间件执行顺序错误
确保自定义中间件EnsureTokenIsValid在StartSession中间件之后执行,Laravel的Session中间件负责Cookie的解析逻辑。可在app/Http/Kernel.php的web中间件组中调整顺序,或注册中间件时指定优先级。Cookie路径设置问题
默认Cookie路径为/,若路由位于子路径下,需显式指定路径:
$cookie = cookie('auth_token', $token, 60 * 24 * 7, '/');
二、自定义中间件中解密Cookie
Laravel默认会自动加密和解密Cookie,只要你的auth_token不在app/Http/Middleware/EncryptCookies.php的$except数组中,使用$request->cookie('auth_token')获取到的就是解密后的明文token。
若需手动解密(特殊场景),可使用Crypt facade:
use Illuminate\Support\Facades\Crypt; // 手动解密Cookie值 $encryptedToken = $request->cookie('auth_token'); $decryptedToken = Crypt::decrypt($encryptedToken);
内容的提问来源于stack exchange,提问作者coolguy123
相关产品推荐
相关产品推荐

