2016-04-24 57 views
8

我有通过快递设置Cookie的问题。我正在使用Este.js dev stack,我尝试在API验证码/login路线中设置Cookie。下面是我在/api/v1/auth/login路线快递不设置Cookie

res.cookie('token', jwt.token, {expires: new Date(Date.now() + 9999999)}); 
res.status(200).send({user, token: jwt.token}); 

使用在src/server/main.js我已经注册cookie-parser作为第一中间件代码

app.use(cookieParser()); 

/api/v1/auth/login航线的响应报头包含

Set-Cookie:token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ.. 

但Cookie未保存在浏览器中document.cookie是空的,也Resources - Cookies选项卡develepoers工具为空):(

编辑: 我发现,当我把这个在/api/v1/auth/login(无来电res.sendres.json

res.cookie('token', jwt.token, {expires: new Date(Date.now() + 9999999), httpOnly: false}); next();

然后cookie被设置为AND响应标头已设置X-Powered-By:Este.js ...这设置esteMiddlewareexpres frontend rendering part

当我使用res.send

res.cookie('token', jwt.token, {expires: new Date(Date.now() + 9999999), httpOnly: false}).send({user, token: jwt.token});` 
next(); 

然后我得到错误Can't set headers after they are sent.,因为使用send方法,使前端呈现抛出这个错误。

但我必须从API发送数据,所以我如何处理这个问题?

可以帮助我吗?谢谢!

+0

你知道它是'document.cookie',而不是'document.cookies'吗?而且,当你查找cookies时,你是否在与'/ api/v1/auth/login'完全相同的域名被发送到? – jfriend00

+1

抱歉错字错误,确定'document.cookie'为空(已编辑)。是的,这是相同的域一切都在'http:// localhost:8000 /' – Mira

+0

@Mira在稍后的请求中cookie可用服务器端 - [''req.cookies.token'](http://expressjs.com/ EN/4X/api.html#req.cookies)?在值之后的'Set-Cookie'头文件中还提供了哪些其他选项? –

回答

0

有几个问题:

  • 不与httpOnly : false在浏览器中明确设置将是可经由document.cookie的cookie。它仍然会被发送HTTP请求,如果你检查你的浏览器的开发工具,你很可能会在那里找到cookie(在Chrome中,它们可以在开发工具的Resources标签中找到);
  • next()只有当您要推迟回复您的应用程序的其他部分(根据您的代码进行判断)不是您想要的内容时,才应该使用您要调用的内容。

所以,在我看来,这应该解决您的问题:

res.cookie('token', jwt.token, { 
    expires : new Date(Date.now() + 9999999), 
    httpOnly : false 
}); 
res.status(200).send({ user, token: jwt.token }); 

作为一个侧面说明:有一个为httpOnly默认为true(以防止恶意XSS脚本访问会话Cookie和原因类似)。如果您没有很好的理由能够通过客户端JS访问cookie,请不要将其设置为false

+1

我已经尝试使用此代码(请参阅第一篇文章),但开发工具的_Resources - Cookie_选项卡仍为空。我不知道为什么cookie不保存在浏览器中:( – Mira

1

我用快递4和节点7.4和角工作,我有同样的问题我帮这样的:
一)服务器端:在文件app.js我给头部像所有响应:

app.use(function(req, res, next) { 
     res.header('Access-Control-Allow-Origin', req.headers.origin); 
     res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 
     next(); 
}); 

这个必须在所有路由器之前。
我看到了很多添加了这个头:

res.header("Access-Control-Allow-Headers","*"); 
res.header('Access-Control-Allow-Credentials', true); 
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); 

但我不需要的是,

B)当你定义者的cookie你的东东添加仅Http:假的,如:

res.cookie(key, value,{ maxAge: 1000 * 60 * 10, httpOnly: false }); 

Ç )客户端:在发送阿贾克斯,你需要添加: “withCredentials:真”,如:

$http({ 
    method: 'POST', 
    url: 'url, 
    withCredentials: true, 
    data : {} 
    }).then(function(response){ 
     // code 
    }, function (response) { 
     // code 
    }); 

好运。

12

我有同样的问题。服务器响应附带cookie集:

Set-Cookie:my_cookie=HelloWorld; Path=/; Expires=Wed, 15 Mar 2017 15:59:59 GMT 

但是,cookie未被浏览器保存。

这就是我解决它的方法。

我在客户端代码中使用fetch。如果您没有在fetch选项中指定credentials: 'include',则Cookie不会被发送到服务器,也不会被浏览器保存,尽管服务器响应会设置cookie。

例子:

var headers = new Headers(); 
headers.append('Content-Type', 'application/json'); 
headers.append('Accept', 'application/json'); 

return fetch('/your/server_endpoint', { 
    method: 'POST', 
    mode: 'same-origin', 
    redirect: 'follow', 
    credentials: 'include', // Don't forget to specify this if you need cookies 
    headers: headers, 
    body: JSON.stringify({ 
     first_name: 'John', 
     last_name: 'Doe' 
    }) 
}) 

希望它可以帮助别人。

+1

您先生,是救命啊! –