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

Laravel 11 Sanctum SPA调用Auth::logoutOtherDevices登出其他设备失败

问题:Sanctum SPA会话认证下调用Auth::logoutOtherDevices()报错

我们在实现基于会话的Sanctum SPA认证(非API令牌)时,用户修改密码后尝试调用Auth::logoutOtherDevices($password);登出其他设备失败,报错信息如下:

error: Method Illuminate\Auth\RequestGuard::logoutOtherDevices does not exist. in /fooapp/vendor/laravel/framework/src/Illuminate/Macroable/Traits/Macroable.php line 115

当前配置

  1. web.php路由:
Route::middleware(['auth:sanctum'])->group(function () {
    Route::put('auth/passwordUpdate', [AuthController::class, 'passwordUpdate']);
});
  1. AuthController.php的passwordUpdate方法:
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Auth;

class AuthController extends BaseController {
    public function passwordUpdate(Request $request) {
        $user = User::where('username', $this->user()->username)->first();

        if (! Hash::check($request->get('password'), $user->password)) {
            return response()->error('Incorrect password provided.');
        }

        try {
            $user->password = Hash::make($request->get('passwordNew'));
            $user->save();

            // Logout user from other devices if they have any active sessions there
            // *** Not working with sanctum at the moment and errors out as seen above
            Auth::logoutOtherDevices($request->get('passwordNew'));
        } catch (\Exception $e) {
            return $this->dbRollbackLogAndReturnError($e, $customErrorMessage);
        }

        return response()->success('You have updated your password successfully.');
    }
}
  1. sanctum.php配置:
<?php

use Laravel\Sanctum\Sanctum;

return [
    ...
    'guard' => ['web'],
    ...
    'middleware' => [
        'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
        'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
        'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
    ],
];
  1. app.php配置:
<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Foundation\Configuration\Exceptions;

return Application::configure(basePath: dirname(__DIR__))
    ->withProviders([
        ...
    ])
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        channels: __DIR__.'/../routes/channels.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
      $middleware->statefulApi(); // sanctum
    })
    ->withExceptions(function (Exceptions $exceptions) {
        ...
    })->create();

解决方案(Laravel 11标准方案)

问题原因

Auth::logoutOtherDevices()是Web守卫(SessionGuard)提供的方法,但当前路由使用auth:sanctum守卫时,默认的Auth门面绑定的是Sanctum的RequestGuard,该守卫没有这个方法。不过你的sanctum配置已指定依赖web守卫,只需明确调用web守卫的实例即可。

具体步骤

  1. 明确指定Web守卫调用方法
    将控制器中的Auth::logoutOtherDevices($request->get('passwordNew'));修改为:
Auth::guard('web')->logoutOtherDevices($request->get('passwordNew'));
  1. 确认中间件生效
    你的sanctum配置已包含AuthenticateSession中间件,该中间件是logoutOtherDevices功能的依赖,确保路由通过auth:sanctum中间件时能自动应用这些配置的中间件(当前配置已满足)。

  2. 优化用户查询(可选)
    当前代码中通过User::where('username', $this->user()->username)->first();查询用户是冗余操作,直接使用$this->user()即可获取当前认证的用户实例:

$user = $this->user();

修改后的控制器代码示例

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Auth;

class AuthController extends BaseController {
    public function passwordUpdate(Request $request) {
        $user = $this->user();

        if (! Hash::check($request->get('password'), $user->password)) {
            return response()->error('提供的密码不正确。');
        }

        try {
            $user->password = Hash::make($request->get('passwordNew'));
            $user->save();

            // 使用web守卫登出其他设备
            Auth::guard('web')->logoutOtherDevices($request->get('passwordNew'));
        } catch (\Exception $e) {
            return $this->dbRollbackLogAndReturnError($e, '密码更新失败');
        }

        return response()->success('密码已成功更新。');
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 01:52:40