Laravel / Vue Passport (SPA) - 将令牌存储到 cookie
Laravel / Vue Passport (SPA) - Store token to cookies
我一直在关注有关 Vue + Laravel 身份验证的教程,一切都已设置,但随后教程转到将令牌存储在本地存储中。我读到这不是应该遵循的最佳实践,因为它更容易受到 XSS 攻击。
问题是很难找到关于在 cookie 中存储令牌的教程(特别是 Laravel + Vue)。谁能帮助解决如何在 cookie 中存储令牌的问题?
非常感谢任何能提供帮助的人。
这是我当前的代码。
控制器
public function login(Request $request)
{
$http = new\GuzzleHttp\Client;
try {
$response = $http->post(config('services.passport.login_endpoint'), [
'form_params' => [
'grant_type' => 'password',
'client_id' => config('services.passport.client_id'),
'client_secret' => config('services.passport.client_secret'),
'username' => $request->username,
'password' => $request->password,
]
]);
return $response->getBody();
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
if ($e->getCode() === 400) {
return response()->json('Invalid Request. Please enter a username or a password.', $e->getCode());
} else if ($e->getCode() === 401) {
return response()->json('Your credentials are incorrect. Please try again', $e->getCode());
}
return response()->json('Something went wrong on the server.', $e->getCode());
}
}
public function logout()
{
auth()->user()->tokens->each(function ($token, $key) {
$token->delete();
});
return response()->json('Logged out successfully', 200);
}
API 航线
Route::post('/login', 'AuthController@login');
Route::middleware('auth:api')->post('/logout', 'AuthController@logout');
Vue 组件脚本
<script>
export default {
props: {
source: String,
},
data: () => ({
username: '',
password: '',
valid: false,
}),
methods: {
save() {
const { username, password } = this
axios
.post('api/login', { username, password })
.then(response => console.log(response))
.catch(error => console.log(error))
}
}
}
</script>
使用document.cookie = response.data.token
在cookie中存储令牌
<script>
export default {
props: {
source: String,
},
data: () => ({
username: '',
password: '',
valid: false,
}),
methods: {
save() {
const { username, password } = this
axios
.post('api/login', { username, password })
.then(response => {
document.cookie = response.data.token
})
.catch(error => console.log(error))
}
}
}
</script>
https://www.w3schools.com/js/js_cookies.asp
获得cookie
var token = document.cookie;
我认为最好的选择是使用 refresh_token
(带有用户数据)作为服务器端 cookie。并将 token
保存在 vue 商店中(您需要从 token
获得的所有内容都是用于用户视图的用户数据)。该解决方案使 XSS 攻击成为不可能。这意味着服务器端 cookie 块 javascript 读取或写入此 cookie。并且每个重新加载页面都需要使用 'autoLogin' 请求和 refresh_token
cookie 进行重新授权(每个请求都自动使用 cookie)例如:
vue 商店例如'auth.ts' 或 'auth.js'
/**
* Autologin user.
*
* @param commit
*/
async autologin({ commit }: any) {
try {
let { data } = await axios.post(`${endpoint}/${silentLogin}`)
setExpiresDateToken(data.accessToken)
commit('auth', {
token: data.accessToken,
idToken: data.idToken,
})
} catch (err) {
localStorage.removeItem('expires')
throw err
}
},
router.ts 或 router.js(我使用 TypeScript)
/**
* Check if user access allows.
* @param to
* @param from
* @param next
* @returns {Promise<void>}
*/
const authGuard = async (to: any, from: any, next: any) => {
if (!store.getters['auth/isAuth']) {
try {
await store.dispatch('auth/autologin')
next()
} catch (e) {
next({ name: 'login' })
}
} else {
next()
}
}
const routes = [
{
path: '/list',
name: 'List',
component: () => import('@/views/DocumentsList'),
beforeEnter: authGuard,
}
]
如果你使用 Laravel 路由器,它可能是类似的方式
我一直在关注有关 Vue + Laravel 身份验证的教程,一切都已设置,但随后教程转到将令牌存储在本地存储中。我读到这不是应该遵循的最佳实践,因为它更容易受到 XSS 攻击。
问题是很难找到关于在 cookie 中存储令牌的教程(特别是 Laravel + Vue)。谁能帮助解决如何在 cookie 中存储令牌的问题?
非常感谢任何能提供帮助的人。
这是我当前的代码。
控制器
public function login(Request $request)
{
$http = new\GuzzleHttp\Client;
try {
$response = $http->post(config('services.passport.login_endpoint'), [
'form_params' => [
'grant_type' => 'password',
'client_id' => config('services.passport.client_id'),
'client_secret' => config('services.passport.client_secret'),
'username' => $request->username,
'password' => $request->password,
]
]);
return $response->getBody();
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
if ($e->getCode() === 400) {
return response()->json('Invalid Request. Please enter a username or a password.', $e->getCode());
} else if ($e->getCode() === 401) {
return response()->json('Your credentials are incorrect. Please try again', $e->getCode());
}
return response()->json('Something went wrong on the server.', $e->getCode());
}
}
public function logout()
{
auth()->user()->tokens->each(function ($token, $key) {
$token->delete();
});
return response()->json('Logged out successfully', 200);
}
API 航线
Route::post('/login', 'AuthController@login');
Route::middleware('auth:api')->post('/logout', 'AuthController@logout');
Vue 组件脚本
<script>
export default {
props: {
source: String,
},
data: () => ({
username: '',
password: '',
valid: false,
}),
methods: {
save() {
const { username, password } = this
axios
.post('api/login', { username, password })
.then(response => console.log(response))
.catch(error => console.log(error))
}
}
}
</script>
使用document.cookie = response.data.token
在cookie中存储令牌
<script>
export default {
props: {
source: String,
},
data: () => ({
username: '',
password: '',
valid: false,
}),
methods: {
save() {
const { username, password } = this
axios
.post('api/login', { username, password })
.then(response => {
document.cookie = response.data.token
})
.catch(error => console.log(error))
}
}
}
</script>
https://www.w3schools.com/js/js_cookies.asp
获得cookie
var token = document.cookie;
我认为最好的选择是使用 refresh_token
(带有用户数据)作为服务器端 cookie。并将 token
保存在 vue 商店中(您需要从 token
获得的所有内容都是用于用户视图的用户数据)。该解决方案使 XSS 攻击成为不可能。这意味着服务器端 cookie 块 javascript 读取或写入此 cookie。并且每个重新加载页面都需要使用 'autoLogin' 请求和 refresh_token
cookie 进行重新授权(每个请求都自动使用 cookie)例如:
vue 商店例如'auth.ts' 或 'auth.js'
/**
* Autologin user.
*
* @param commit
*/
async autologin({ commit }: any) {
try {
let { data } = await axios.post(`${endpoint}/${silentLogin}`)
setExpiresDateToken(data.accessToken)
commit('auth', {
token: data.accessToken,
idToken: data.idToken,
})
} catch (err) {
localStorage.removeItem('expires')
throw err
}
},
router.ts 或 router.js(我使用 TypeScript)
/**
* Check if user access allows.
* @param to
* @param from
* @param next
* @returns {Promise<void>}
*/
const authGuard = async (to: any, from: any, next: any) => {
if (!store.getters['auth/isAuth']) {
try {
await store.dispatch('auth/autologin')
next()
} catch (e) {
next({ name: 'login' })
}
} else {
next()
}
}
const routes = [
{
path: '/list',
name: 'List',
component: () => import('@/views/DocumentsList'),
beforeEnter: authGuard,
}
]
如果你使用 Laravel 路由器,它可能是类似的方式