Vue.js / Laravel - 正确处理注销
Posted
技术标签:
【中文标题】Vue.js / Laravel - 正确处理注销【英文标题】:Vue.js / Laravel - Handle logout correctly 【发布时间】:2019-01-31 22:26:13 【问题描述】:我目前正在尝试使用 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')
但是,当用户点击注销功能时,他们不会立即注销(重定向到登录页面)——他们仍然可以浏览“仅限用户页面”。
我必须在正确注销之前刷新页面。
谁能帮我解决这个问题?这甚至是“安全”注销功能的正确方法吗?
【问题讨论】:
【参考方案1】:要注销安装 axios 并在 Laravel 6* / 7* / 8* 中执行其余代码
npm install axios
点击注销时触发此代码
axios.post("logout").then(response =>
console.log(response);
)
.catch(error =>
console.log(error);
);
【讨论】:
【参考方案2】:这有点老了,但是,我刚开始使用 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();
除了在你的头脑中添加一个元 csrf(blade.php 文件),像这样:
<meta name="csrf-token" content=" csrf_token()">
我假设您将在导航栏 .vue 文件中使用注销
【讨论】:
【参考方案3】:对于我的注销链接,我想向 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】:尝试在成功注销时使用 javascript 重定向:
window.location.replace("desiredURL");
【讨论】:
我更喜欢在 Vue 中处理一切【参考方案5】:我自己从未使用过 Laravel,但您应该能够在客户端处理注销,而无需在后端执行任何操作。目前您从本地存储中删除身份验证令牌,因此用户无法访问需要您登录才能获取的数据。
当您刷新页面时,您可能会调用您的getUser
,这就是为什么您当时只注销 - 您将空令牌发送到后端服务器,它找不到与之关联的用户并返回一个空/默认来宾对象。剩下要做的就是在删除 logout()
函数中的令牌或向 /get-user
端点发送请求后清除您的用户状态。
【讨论】:
听起来正确。关于如何实现这一点的任何想法?一个例子?抱歉,我对 Vue 很陌生 在localStorage.removeItem('expiration')
之后做类似axios.get('/api/get-user').then(response => <your_user_data_state> = response.data ).catch(err => console.log(err.response.data))
的事情
你不需要注销路由来处理注销;您需要重置您现在在页面刷新时执行的用户状态。以上是关于Vue.js / Laravel - 正确处理注销的主要内容,如果未能解决你的问题,请参考以下文章
使用 Laravel 作为后端刷新 Vue.js SPA 的身份验证令牌
如何正确地将数据从 vue 组件发布到 laravel 控制器
有没有更好的方法来处理 laravel 和 vue js 的 axios 错误