2016-04-24 52 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

您先生,是救命啊! –