我目前正在尝试使用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')
}
但是,当用户单击注销功能时,他们不会立即注销(重定向到登录页面)-他们仍然可以浏览“仅用户页面”。
在正确注销之前,我必须刷新页面。
有人可以协助我吗?这甚至是“安全”注销功能的正确方法吗?
答案 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文件中使用注销信息