0

在我注销并想要重新登录后,我收到以下错误:

消息:“CSRF 令牌不匹配。”,异常:“Symfony\Component\HttpKernel\Exception\HttpException”

我定制了一些部分,LoginController所以它可能与此有关。我尝试在未修改的情况下进行搜索,LoginController但找不到任何东西。我vuex商店的登录功能:

login({ commit }, user) {
    return new Promise((resolve, reject) => {
        axios({ url: '/login', data: user, method: 'POST' })
            .then(response => {
                const user = response.data.user
                commit('auth_success', user)
                resolve(response)
            })
            .catch(error => {
                commit('auth_error')
                reject(error)
            })
    })
},

我的注销功能,也来自我的vuex商店:

logout({ commit }) {
    return new Promise((resolve, reject) => {
        axios({ url: '/logout', method: 'POST' })
            .then(() => {
                commit('logout')
                localStorage.removeItem('user');
                resolve()
            })
            .catch(error => {
                reject(error)
            })
    })
},

这是我的登录控制器:

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{

    use AuthenticatesUsers;

    protected $redirectTo = RouteServiceProvider::HOME;    

    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    public function login(Request $request)
    {

        if ($this->attemptLogin($request)) {

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

            return $this->authenticated($request, $this->guard()->user());
        }
    }

    protected function attemptLogin(Request $request)
    {
        return $this->guard()->attempt(['email' => $request->json('email'), 'password' => $request->json('password')]);
    }

    protected function authenticated(Request $request, $user)
    {
        if ($user) {
            return response()->json([
                'user' => $user
            ], 200);
        } else {
            return response('', 400);
        }
    }

    public function logout(Request $request)
    {
        $this->guard()->logout();

        if ($request->session()->invalidate()) {
            return response('', 200);
        }
    }
}

我错过了什么吗?

更新: 如果我刷新页面,我不会再收到错误消息。这可能与我有一个使用vue-router. 所以我想我需要刷新页面以避免 419 错误。但这不是一个理想的情况。有人有这方面的经验吗?

4

1 回答 1

1

在 SAP 中,您的浏览器仍然保存所有您没有明确清除的 JS 变量。听起来当您退出 SAP 时,您正在生成一个新的 CSRF 令牌,但没有清除您的 JS 变量。CSRF 保护然后检查你是否已经有一个 CSRF 令牌,当它找到它并看到不匹配时,它假定你正在尝试 CSRF 攻击并阻止你。一般来说,最好在注销时强制重新加载页面以清除您的 JS 变量,因为不这样做可能会导致下一个用户看到您可能忘记清除的所有其他私有数据。

在结束时使用以下 JS 响应,您的注销过程将自动触发用户浏览器的刷新。

// Reloads the current URL.
location.reload();

如果您绝对不想重新加载页面,则需要清除所有本地数据,而不仅仅是“用户”对象。我知道的最好的方法如下:

// Clear all JS variables for the current domain.
localStorage.clear();
sessionStorage.clear();

在注销时,我个人更喜欢重新加载,因为它还会提示缓存重新验证非 JS 本地数据,这可以防止某些其他类型的韭菜,例如显示上一个用户会话中的新用户图像。

于 2020-01-02T18:29:26.723 回答