简体   繁体   English

使用 event.preventDefault 时无法从 Laravel 应用程序注销。 替代?

[英]Unable to logout from Laravel application when using event.preventDefault. Alternative?

So I a couple of forms in my application looking like this :所以我的应用程序中有几个表单看起来像这样:

<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
    {!! Form::open(['action'=>['AdminController@update',$upload->id,0], 'method'=>'POST']) !!}
    {{Form::hidden('_method','PUT')}}
    <a class="dropdown-item" href="/manage">Approve</a>
    {!! Form::close()!!}

    {!! Form::open(['action'=>['AdminController@update',$upload->id,1], 'method'=>'POST']) !!}
    {{Form::hidden('_method','PUT')}}
    <a class="dropdown-item" href="/manage">Reject</a>
    {!! Form::close()!!}

</div>

I am sending these forms using the following jQuery snippet:我使用以下 jQuery 代码段发送这些表单:

$(".dropdown-item").click(function(e){
    e.preventDefault();
    $(this).closest("form").submit();
});

I noticed that when this snippet is not commented out, I am unable to log out from my Laravel app.我注意到当这个片段没有被注释掉时,我无法从我的 Laravel 应用程序中注销。 The log out just doesn't work.注销是行不通的。

I am using standard Laravel authentication.我正在使用标准的 Laravel 身份验证。

This is part of how I log out:这是我注销方式的一部分:

<a class="dropdown-item" href="#" onclick="window.location='{{ route('logout') }}'">Log out</a>

First, can someone explain why this is happening?首先,有人可以解释为什么会这样吗? I tried to investigate, but what I read didn't make much sense, since I am new to all of this.我试图调查,但我读到的东西没有多大意义,因为我对这一切都不熟悉。

And what would be the workaround here?这里的解决方法是什么? How can I send these forms without the preventdefault method?如何在没有preventdefault方法的情况下发送这些表单? Or how can I log out while using it?或者我如何在使用它时注销? I'd prefer not to change my log out functionality.我不想更改我的注销功能。

So to log out the user, you need to hit route('logout') which is a predefined route when you scaffold laravel auth system.因此,要注销用户,您需要点击route('logout') ,这是在搭建 laravel 身份验证系统时的预定义路由。

The logout route its definded under /src/Illuminate/Routing/Router.php line 1125. It needs to be a post request in order to logout the user, there are no required parameters to be sent expect laravel csrf token, which is the token to make sure that the requests are comming from the app itself and not any external script.注销路由定义在/src/Illuminate/Routing/Router.php行 1125 下。它需要是一个 post 请求才能注销用户,除了 laravel csrf 令牌之外,没有需要发送的参数,这是令牌确保请求来自应用程序本身而不是任何外部脚本。

If you go to logout function which is hidden under LoginController you will see a trait(simply to keep the class cleaner) AuthenticatesUser Trait it is responsible to logout the user.如果您转到隐藏在LoginController下的注销功能,您将看到一个特征(只是为了保持类清洁) AuthenticatesUser Trait 它负责注销用户。

In AuthenticatesUser trait you will find a method at line 151:AuthenticatesUser trait 你会在第 151 行找到一个方法:

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

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

    return redirect('/');
}

which in simple terms it logs user out of session guard (Guards define how users are authenticated for each request.) and then destroys the session and the user its logged out with a redir to homepage.简单来说,它将用户从会话防护中注销(防护定义了用户如何为每个请求进行身份验证。)然后销毁会话,用户通过重定向到主页将其注销。

Now as said we need a post request with csrf token to log the user out:现在如上所述,我们需要一个带有 csrf 令牌的 post 请求来注销用户:

    <a href="{{ route('logout') }}"
      onclick="event.preventDefault();       

       document.getElementById('logout-form').submit();">
       Logout
   </a>

Form placed under the a href tag放置在a href标签下的表单

 <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
     {{ csrf_field() }}
 </form>

The a href tag which has event.preventDefault() which in simple terms means prevent a href tag from acting how normally it acts.具有event.preventDefault()a href标签,简单来说意味着阻止 href 标签的正常行为。 That being said a href tag will not redirect to the route, instead we have document.getElementById('logout-form').submit();"> which simply gets the form logout-form and submits it whenever the user clicks on that a href tag也就是说, a href标签不会重定向到路由,而是我们有document.getElementById('logout-form').submit();">它只是获取表单logout-form并在用户点击它时提交它a href tag

Or simply change 'dropdown-item' class name for your logout form , since prolly that is being frozen when both forms are active.或者简单地更改注销表单的“下拉项”类名称,因为当两个表单都处于活动状态时,它会被冻结。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM