Ege*_*soz 35 cookies session-cookies reactjs vue.js vuejs2
几天来,我一直在为单页面应用程序寻找安全的身份验证和会话管理机制.从有关SPA和身份验证的众多教程和博客文章来看,将JWT存储在localStorage或常规cookie中似乎是最常用的方法,但将JWT用于会话并不是一个好主意因此它不是这个应用程序的选项.
要求
理想的机制似乎是使用HttpOnly包含会话ID的cookie进行基于cookie的身份验证.流程将如下工作:
HttpOnly响应cookie 发送.withCredentials选项.因为cookie具有HttpOnly标志,JavaScript将无法读取其内容,因此只要通过HTTPS传输,它就不会受到攻击.
挑战
这是我遇到的具体问题.我的服务器配置为处理CORS请求.在对用户进行身份验证后,它会在响应中正确发送cookie:
HTTP/1.1 200 OK
server: Cowboy
date: Wed, 15 Mar 2017 22:35:46 GMT
content-length: 59
set-cookie: _myapp_key=SFMyNTYBbQAAABBn; path=/; HttpOnly
content-type: application/json; charset=utf-8
cache-control: max-age=0, private, must-revalidate
x-request-id: qi2q2rtt7mpi9u9c703tp7idmfg4qs6o
access-control-allow-origin: http://localhost:8080
access-control-expose-headers:
access-control-allow-credentials: true
vary: Origin
Run Code Online (Sandbox Code Playgroud)
但是,浏览器不保存cookie(当我检查Chrome的本地cookie时,它不存在).因此,当以下代码运行时:
context.axios.post(LOGIN_URL, creds).then(response => {
context.$router.push("/api/account")
}
Run Code Online (Sandbox Code Playgroud)
并创建帐户页面:
created() {
this.axios.get(SERVER_URL + "/api/account/", {withCredentials: true}).then(response => {
//do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
此调用在标头中没有cookie.因此服务器拒绝它.
GET /api/account/ HTTP/1.1
Host: localhost:4000
Connection: keep-alive
Accept: application/json
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8,tr;q=0.6
Run Code Online (Sandbox Code Playgroud)
我是否需要做一些特别的事情以确保浏览器在登录响应中收到cookie后保存cookie?我读过的各种来源都说浏览器只在用户被重定向时保存响应cookie,但我不想要任何"硬"重定向,因为这是一个SPA.
有问题的SPA是用Vue.js编写的,但我想它适用于所有SPA.我想知道人们如何处理这种情况.
我读过关于这个主题的其他内容:
小智 7
我在 Vue.js 2 上使用凭据 = true 完成了这项工作。从客户端设置凭据只是故事的一半。您还需要设置来自服务器的响应标头:
header("Access-Control-Allow-Origin: http://localhost:8080");
header("Access-Control-Allow-Credentials: true");
Run Code Online (Sandbox Code Playgroud)
您不能像这样对 Access-Control-Allow-Origin 使用通配符:
header("Access-Control-Allow-Origin: *");
Run Code Online (Sandbox Code Playgroud)
当您指定凭据:true 标头时,您需要指定来源。
如您所见,这是一段 PHP 代码,您可以将其建模为 NodeJS 或您正在使用的任何服务器端脚本语言。
在VueJS中,我在main.js中像这样设置了credentials = true:
Vue.http.options.credentials = true
Run Code Online (Sandbox Code Playgroud)
在组件中,我使用ajax成功登录:
<template>
<div id="userprofile">
<h2>User profile</h2>
{{init()}}
</div>
</template>
<script>
export default {
name: 'UserProfile',
methods: {
init: function() {
// loggin in
console.log('Attempting to login');
this.$http.get('https://localhost/api/login.php')
.then(resource => {
// logging response - Notice I don't send any user or password for testing purposes
});
// check the user profile
console.log('Getting user profile');
this.$http.get('https://localhost/api/userprofile.php')
.then(resource => {
console.log(resource.data);
})
}
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
在服务器端,事情非常简单:Login.php 设置了一个 cookie 而不进行任何验证(注意:这仅用于测试目的。不建议您在未经验证的情况下在生产中使用此代码)
<?php
header("Access-Control-Allow-Origin: http://localhost:8080");
header("Access-Control-Allow-Credentials: true");
$cookie = setcookie('user', 'student', time()+3600, '/', 'localhost', false , true);
if($cookie){
echo "Logged in";
}else{
echo "Can't set a cookie";
}
Run Code Online (Sandbox Code Playgroud)
最后,userprofile.php 只是验证是否设置了 cookie = user
<?php
header("Access-Control-Allow-Origin: http://localhost:8080");
header("Access-Control-Allow-Credentials: true");
if(isset($_COOKIE['user'])){
echo "Congratulations the user is ". $_COOKIE['user'];
}else{
echo "Not allowed to access";
}
Run Code Online (Sandbox Code Playgroud)
登录成功
| 归档时间: |
|
| 查看次数: |
8785 次 |
| 最近记录: |