Sanctum SPA 身份验证:如何从其他设备注销?

Sanctum SPA Authentication: How to log out from other devices?

SPA 身份验证中是否包含此功能?通过阅读 Laravel Sanctum 上的文档,它看起来不像,但与此同时,这是一个常见的功能(如果用户重置密码或您只需要一个用户的登录实例)所以我认为它必须包括在内...

经过搜索,我发现了这个:

use Illuminate\Support\Facades\Auth;

Auth::logoutOtherDevices($currentPassword);

但您需要先在网络上取消对这个中间件的注释,然后才能使用它。

'web' => [
    // ...
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    // ...
],

然而,这仅适用于网络,不适用于 api。所以我再次用谷歌搜索如何使用 api 具有相同的功能,然后我找到了 this youttube video。这是这个人所做的:

  1. 创建自己的中间件(例如 AuthenticateSessionSPA.php)。
  2. 复制 AuthenticateSession 中的所有内容并将其粘贴到新的中间件中。更改命名空间和 class 名称。
  3. 创建值为 'sanctum' 的私有变量(例如 private $driver = 'sanctum')
  4. 将所有 $this->auth->getDefaultDriver() 替换为 $this->driver。所以 该代码将改用 sanctum 驱动程序。

文件如下所示:

<?php

namespace App\Http\Middleware\Custom;

use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Contracts\Auth\Factory as AuthFactory;

class AuthenticateSessionSPA
{
    private $driver = 'sanctum';

    /**
     * The authentication factory implementation.
     *
     * @var \Illuminate\Contracts\Auth\Factory
     */
    protected $auth;

    /**
     * Create a new middleware instance.
     *
     * @param  \Illuminate\Contracts\Auth\Factory  $auth
     * @return void
     */
    public function __construct(AuthFactory $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (! $request->hasSession() || ! $request->user()) {
            return $next($request);
        }

        if ($this->guard()->viaRemember()) {
            $passwordHash = explode('|', $request->cookies->get($this->auth->getRecallerName()))[2] ?? null;

            if (! $passwordHash || $passwordHash != $request->user()->getAuthPassword()) {
                $this->logout($request);
            }
        }

        if (! $request->session()->has('password_hash_'.$this->driver)) {
            $this->storePasswordHashInSession($request);
        }

        if ($request->session()->get('password_hash_'.$this->driver) !== $request->user()->getAuthPassword()) {
            $this->logout($request);
        }

        return tap($next($request), function () use ($request) {
            if (! is_null($this->guard()->user())) {
                $this->storePasswordHashInSession($request);
            }
        });
    }

    /**
     * Store the user's current password hash in the session.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    protected function storePasswordHashInSession($request)
    {
        if (! $request->user()) {
            return;
        }

        $request->session()->put([
            'password_hash_'.$this->driver => $request->user()->getAuthPassword(),
        ]);
    }

    /**
     * Log the user out of the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     *
     * @throws \Illuminate\Auth\AuthenticationException
     */
    protected function logout($request)
    {
        $this->guard()->logoutCurrentDevice();

        $request->session()->flush();

        throw new AuthenticationException('Unauthenticated.', [$this->driver]);
    }

    /**
     * Get the guard instance that should be used by the middleware.
     *
     * @return \Illuminate\Contracts\Auth\Factory|\Illuminate\Contracts\Auth\Guard
     */
    protected function guard()
    {
        return $this->auth;
    }
}

这非常有效,我现在可以在 api.

中使用 Auth::logoutOtherDevices($currentPassword)

所以我的问题是这是否安全?我只是个jr开发(6 个月),我对这个解决方案不太有信心,因为我是从网上的某个人那里找到的,而不是从文档中找到的。我想知道也许 laravel 开发人员没有实施它是因为他们出于安全原因?

你对这个方法有什么看法?如果您不同意这一点,您将如何在具有 SPA 前端和 Laravel api 的项目中实现从其他设备注销?

Laravel Sanctum SPA 身份验证中似乎没有包含此内容。所以我只是做了我在 the youtube video

上找到的原始答案