Vue.js / Laravel-正确处理注销

时间:2018-08-25 21:33:54

标签: php laravel vue.js vuejs2

我目前正在尝试使用Vue和Laravel创建一个简单的SPA。我掌握了基本的知识-用户可以注册和登录。

我只是不知道如何创建注销功能。

这是我目前拥有的:

AuthController.php

public function logout()
{
        $accessToken = auth()->user()->token();

        $refreshToken = DB::table('oauth_refresh_tokens')
        ->where('access_token_id', $accessToken->id)
        ->update([
            'revoked' => true
        ]);

        $accessToken->revoke();

        return response()->json(['status' => 200]);
}

routes/api.php

Route::middleware('auth:api')->group(function () {
    Route::post('/logout', 'API\AuthController@logout');
    Route::get('/get-user', 'API\AuthController@getUser');
});

现在,这是我尝试做的事情:

Layout.vue

methods: {
            logout() {
                axios.post('/api/logout').then(response => {
                    this.$router.push("/login")

                }).catch(error => {
                    location.reload();
                });
            }
 }

哪个在Auth.js中调用我的注销功能:

logout() {
    localStorage.removeItem('token')
    localStorage.removeItem('expiration')
}

但是,当用户单击注销功能时,他们不会立即注销(重定向到登录页面)-他们仍然可以浏览“仅用户页面”。

在正确注​​销之前,我必须刷新页面。

有人可以协助我吗?这甚至是“安全”注销功能的正确方法吗?

5 个答案:

答案 0 :(得分:1)

退出安装 axios 并在 Laravel 6* / 7* / 8* 中执行其余代码

npm install axios

点击注销时触发此代码

axios.post("logout").then(response => { 
   console.log(response);
})
.catch(error => {
   console.log(error);
});

答案 1 :(得分:0)

我自己从未使用过Laravel,但是您应该能够处理客户端注销,而无需在后端执行任何操作。目前,您从本地存储中删除身份验证令牌,因此用户无法访问需要登录才能获取的数据。

刷新页面时,您可能会调用getUser,这就是为什么您仅退出后的原因-您将空令牌发送到后端服务器,该后端服务器找不到与之关联的用户并返回一个空/默认来宾对象。剩下要做的就是在删除logout()函数中的令牌或向/get-user端点发送请求之后清除用户状态。

答案 2 :(得分:0)

尝试在成功注销后使用javascript重定向:

window.location.replace("desiredURL");

答案 3 :(得分:0)

对于我的注销链接,我想向Laravel请求使当前用户的(Passport JWT)令牌无效。

这是我的做法:

在我的后端

AuthController.php

我有一个注销方法:

  ...

  public function logout(Request $request) {
    $request->user()->token()->revoke();

    return response()->json([
       'message' => 'Successfully logged out'
    ]);
  }

routes/api.php

我有一条只能通过身份验证才能访问的路由。

Route::group(['middleware' => 'auth:api'], function() {
  ...

  Route::get('/logout', 'AuthController@logout');
});

我的前端

为此,我正在使用Vue的single file components

App.vue

<template>
  <nav>
    <ul>
      ...
        <li v-if="isLoggedIn">
          <a id="logout-link" href="#" @click.prevent="logout">Logout</a>
        </li>
    </ul>
  </nav>
  ...
</template>

<script>
export default {
   ...
   methods: {
     logout(evt) {
       if(confirm("Are you sure you want to log out?")) {
         axios.get('api/logout').then(response => {
          localStorage.removeItem('auth_token');

          // remove any other authenticated user data you put in local storage

          // Assuming that you set this earlier for subsequent Ajax request at some point like so:
          // axios.defaults.headers.common['Authorization'] = 'Bearer ' + auth_token ;
          delete axios.defaults.headers.common['Authorization'];

          // If using 'vue-router' redirect to login page
          this.$router.go('/login');
        })
        .catch(error => {
          // If the api request failed then you still might want to remove
          // the same data from localStorage anyways
          // perhaps this code should go in a finally method instead of then and catch
          // methods to avoid duplication.
          localStorage.removeItem('auth_token');
          delete axios.defaults.headers.common['Authorization'];
          this.$router.go('/login');
        });       
       }
     }
   }
}
</script>

此方法的重点是注销后使后端的令牌无效。但是,如果令牌的有效期短,则可能没有必要这样做。

答案 4 :(得分:0)

那有点老,但是,我刚开始使用Laravel / Vue,并设法做到这一点很简单。使用Laravel的集成身份验证,您可以像这样模拟从app.blade.php注销:

<b-dropdown-item href="#" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">Sign Out</b-dropdown-item> //that's instead of a regular <a> tag
<b-form id="logout-form" action="logout" method="POST" style="display: none;">
   <input type="hidden" name="_token" :value="csrf">
</b-form>

您需要使csrf令牌通过脚本中的数据传递,才能使其正常工作:

export default {
 data() {
   return {
     csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content')
   }
 },
 methods: {
   submit : function(){
     this.$refs.form.submit();
   }
 }
}

像这样在您的头部(blade.php文件)中添加一个元csrf:

<meta name="csrf-token" content="{{ csrf_token()}}">

我假设您将在navbar .vue文件中使用注销信息

相关问题