英文:
Laravel / Vue Passport (SPA) - Store token to cookies
问题
我一直在跟踪一个关于Vue + Laravel身份验证的教程,一切都已经设置好了,但是然后教程提到了将令牌存储在本地存储中。我已经阅读到这不是最佳实践,因为它更容易受到XSS攻击的影响。
问题在于很难找到关于将令牌存储在Cookie中的教程(特别是Laravel + Vue)。是否有人可以帮助我如何实现将令牌存储在Cookie中?
非常感谢任何能提供帮助的人。
以下是我的当前代码。
Controller(控制器)
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>
希望这可以帮助你。
英文:
I have been following a tutorial about Vue + Laravel authentication and everything is set-up but then the tutorial went to storing tokens in a local storage. I have read that this is not the best practice that should be followed since it is more susceptible to an XSS attack.
The problem is that it is very hard to find a tutorial about storing tokens in a cookie (specifically Laravel + Vue). Can anyone please help on how to implement storing tokens in a cookie?
Thank you very much for anyone who could help.
Here is my current code.
Controller
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 routes
Route::post('/login', 'AuthController@login');
Route::middleware('auth:api')->post('/logout', 'AuthController@logout');
Vue Component Script
<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>
答案1
得分: 6
使用以下代码将令牌存储在 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>
要获取 cookie 中的令牌,请使用以下 JavaScript 代码:
var token = document.cookie;
有关更多有关 cookie 的信息,可以查看这个链接。
英文:
Use document.cookie = response.data.token
to store token in 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
to get cookie
var token = document.cookie;
答案2
得分: 3
我认为最佳选择是将refresh_token
(带有用户数据)用作服务器端cookie,并将token
保存在Vue存储中(从token
中需要的一切是用户视图的用户数据)。这个解决方案可以防止XSS攻击。这意味着服务器端的cookie会阻止JavaScript读取或写入该cookie。并且在每次重新加载页面时,您需要使用带有refresh_token
cookie的'autoLogin'请求进行重新授权(每个请求都会自动使用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路由器,可能有类似的方式。
英文:
I think the best option is to use refresh_token
(with user data) as a server-side cookie. And save token
in vue store (everything that you need from token
is user data for user view). This solution makes an impossible XSS attack. This means server-side cookie block javascript to read or write this cookie. And every reloads pages you need to use 'autoLogin' request with refresh_token
cookie for reauthorization (every request use automatically cookie) e.g.:
vue store e.g. 'auth.ts' or '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 or router.js (I user 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,
}
]
If you use Laravel routers it mas be a similar way
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论