2016-04-24 20 views
8

Tôi gặp sự cố khi đặt cookie thông qua chuyển phát nhanh. Tôi đang sử dụng Este.js dev stack và tôi cố gắng đặt cookie trong API auth /login tuyến đường. Dưới đây là đoạn code mà tôi sử dụng trong /api/v1/auth/login đườngExpress không đặt cookie

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

Trong src/server/main.js Tôi đã đăng ký cookie-parser như middleware đầu tiên

app.use(cookieParser()); 

Tiêu đề phản ứng cho /api/v1/auth/login đường chứa

Set-Cookie:token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ.. 

nhưng cookie không được lưu trong trình duyệt (document.cookie là trống rỗng, cũng Resources - Cookies tab trong công cụ develepoers là trống) :(

EDIT: Tôi thấy rằng khi tôi gọi đây là trong /api/v1/auth/login (không gọi res.send hoặc res.json)

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

thì cookie được đặt VÀ tiêu đề phản hồi đã đặt X-Powered-By:Este.js ... bộ này esteMiddleware trong expres frontend rendering part.

Khi tôi sử dụng res.send

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

sau đó tôi nhận được lỗi Can't set headers after they are sent.send phương pháp được sử dụng, vì vậy lối làm ném lỗi này.

Nhưng tôi phải gửi dữ liệu từ API, vậy làm thế nào tôi có thể giải quyết vấn đề này?

Một số người có thể giúp tôi không? Cảm ơn!

+0

Bạn có nhận ra rằng đó là 'document.cookie', không phải' document.cookies'? Và, khi bạn tìm kiếm các tập tin cookie là bạn trong một trang với cùng một tên miền như '/ api/v1/auth/login' đã được gửi đến? – jfriend00

+1

Xin lỗi vì lỗi đánh máy, chắc chắn 'document.cookie' trống (đã chỉnh sửa). Có, tất cả mọi thứ trong cùng một miền đều có tại http: // localhost: 8000/' – Mira

+0

@Mira Là cookie có sẵn phía máy chủ trong các yêu cầu sau này - [' req.cookies.token'] (http://expressjs.com/ vi/4x/api.html # req.cookies)? Các tùy chọn khác được đưa ra trong tiêu đề 'Đặt-Cookie' sau giá trị? –

Trả lời

0

Có một vài vấn đề:

  • một cookie đó không rõ ràng thiết lập với httpOnly : false sẽ không có thể truy cập thông qua document.cookie trong trình duyệt. Nó sẽ vẫn được gửi với các yêu cầu HTTP và nếu bạn kiểm tra các công cụ tìm kiếm của trình duyệt, bạn sẽ tìm thấy cookie đó (trong Chrome chúng có thể được tìm thấy trong tab Tài nguyên của các công cụ dành cho nhà phát triển);
  • next() mà bạn đang gọi chỉ nên được sử dụng nếu bạn muốn trì hoãn việc gửi trả lời cho một số phần khác của ứng dụng, điều này — đánh giá bằng mã của bạn — không phải là điều bạn muốn.

Vì vậy, có vẻ như với tôi rằng điều này sẽ giải quyết vấn đề của bạn:

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

Như một mặt lưu ý: có một lý do cho httpOnly mặc định cho true (để ngăn chặn kịch bản XSS độc hại từ việc truy cập các tập tin cookie phiên và như thế). Nếu bạn không có lý do chính đáng để có thể truy cập cookie thông qua JS phía máy khách, không đặt nó thành false.

+1

Tôi đã cố gắng sử dụng mã này (xem bài đăng đầu tiên) nhưng _Resources - tab Cookie_ của các công cụ dev vẫn còn trống. Tôi không biết tại sao cookie không được lưu trong trình duyệt :( – Mira

1

tôi làm việc với tốc 4 và nút 7.4 và góc cạnh, tôi đã cùng một vấn đề để tôi giúp này:
a) phía máy chủ: trong app.js tập tin tôi cung cấp cho tiêu đề cho tất cả các câu trả lời như:

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(); 
}); 

phải có trước tất cả bộ định tuyến.
tôi thấy rất nhiều thêm tiêu đề này:

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

nhưng tôi không cần điều đó,

b) khi bạn Definer Cookie bạn nee thêm HttpOnly: false, như:

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

c) phía máy khách: trong gửi ajax bạn cần thêm: "withCredentials: true", như:

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

chúc may mắn.

12

Tôi gặp vấn đề tương tự. Phản hồi của máy chủ đi kèm với tập hợp cookie:

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

Nhưng cookie không được lưu bởi trình duyệt.

Đây là cách tôi đã giải quyết.

Tôi sử dụng fetch trong mã phía máy khách. Nếu bạn không chỉ định credentials: 'include' trong các tùy chọn fetch, cookie sẽ không được gửi đến máy chủ hoặc cũng không được lưu bởi trình duyệt, mặc dù phản hồi của máy chủ đặt cookie.

Ví dụ:

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' 
    }) 
}) 

Hy vọng nó sẽ giúp ai đó.

+1

Bạn thưa bạn, là người tiết kiệm cuộc sống! –

Các vấn đề liên quan