Làm cho Axios tự động gửi cookie theo yêu cầu của nó


121

Tôi đang gửi yêu cầu từ máy khách đến máy chủ Express.js của mình bằng Axios.

Tôi đặt một cookie trên máy khách và tôi muốn đọc cookie đó từ tất cả các yêu cầu của Axios mà không cần thêm chúng theo cách thủ công để yêu cầu bằng tay.

Đây là ví dụ về yêu cầu phía khách hàng của tôi:

axios.get(`some api url`).then(response => ...

Tôi đã cố gắng truy cập tiêu đề hoặc cookie bằng cách sử dụng các thuộc tính này trong máy chủ Express.js của mình:

req.headers
req.cookies

Không ai trong số họ chứa bất kỳ cookie nào. Tôi đang sử dụng phần mềm trung gian phân tích cú pháp cookie:

app.use(cookieParser())

Làm cách nào để Axios tự động gửi cookie theo yêu cầu?

Biên tập:

Tôi đặt cookie trên máy khách như sau:

import cookieClient from 'react-cookie'

...
let cookie = cookieClient.load('cookie-name')
if(cookie === undefined){
      axios.get('path/to/my/cookie/api').then(response => {
        if(response.status == 200){
          cookieClient.save('cookie-name', response.data, {path:'/'})
        }
      })
    }
...

Trong khi nó cũng sử dụng Axios, nó không liên quan đến câu hỏi. Tôi chỉ muốn nhúng cookie vào tất cả các yêu cầu của mình sau khi cookie được đặt.


1
bạn đã đặt cookie trên máy khách như thế nào? chương trình ví dụ mã xin vui lòng :)
Tzook Bar Noy

@TzookBarNoy Đã thêm mã được đề cập
Kunok

Cookie được thiết lập bởi máy chủ với Set-Cookie chứ không phải bởi máy khách, tôi đoán ý bạn là đang đọc cookie trên máy khách. Theo giao thức Cookie, khách hàng nên bao gồm tiêu đề Cookie trong các yêu cầu của nó tới máy chủ của nhà phát hành cookie.
Hans Poo

Câu trả lời:


241

Tôi đã gặp vấn đề tương tự và đã khắc phục nó bằng cách sử dụng thuộc withCredentialstính.

XMLHttpRequest từ một miền khác không thể đặt giá trị cookie cho miền riêng của chúng trừ khi withCredentials được đặt thành true trước khi thực hiện yêu cầu.

axios.get('some api url', {withCredentials: true});

8
Nếu bạn đang cố gắng kết nối với một ứng dụng Express - bạn sẽ cần sử dụng cors và sử dụng các cài đặt này. Nguồn gốc của yêu cầu là bắt buộc. app.use (cors ({thông tin xác thực: true, origin: ' localhost: 8080 '}));
DogCoffee

17
lưu ý rằng điều này sẽ chỉ hoạt động khi Access-Control-Allow-Origintiêu đề trong phản hồi không được đặt thành ký tự đại diện (*)
Jerry Zhang

1
@JerryZhang Ý bạn là gì? Tôi đang phải đối mặt với cùng một vấn đề, nếu Access-Control-Allow-Originkhông được thiết lập để *nó có nghĩa là, tôi sẽ không thực hiện yêu cầu đến máy chủ vì CORS đúng
samayo

5
Phản hồi cần đặt Access-Control-Allow-Origingiá trị của miền mà bạn muốn thực hiện yêu cầu XHR. ví dụ https://a.comlà máy chủ, https://b.comlà máy khách, và https://b.comđược tải trong trình duyệt của ai đó và đang sử dụng XMLHTTPRequestđể thực hiện yêu cầu https://a.com. Ngoài ra cho XMLHTTPRequest(bắt đầu vào https://a.com) để thiết lập withCredential: true, máy chủ - https://b.comcũng cần phải được cấu hình để tiêu đề phản ứng chứaAccess-Control-Allow-Origin: https://a.com
Jerry Zhang

Tôi có một chút vấn đề với điều này ... nếu tôi có một máy chủ b là máy khách (tức là trang phản ứng), hơn là nếu tôi đặt điều này thành true, nó sẽ gửi thông tin đăng nhập chứ không phải thông tin đăng nhập b ... LOL. .. OK, không có gì vui đâu.
golddragon007,

24

TL; DR:

{ withCredentials: true } hoặc là axios.defaults.withCredentials = true


Từ tài liệu axios

withCredentials: false, // default

withCredentials cho biết có nên thực hiện các yêu cầu Kiểm soát truy cập trên nhiều trang bằng thông tin đăng nhập hay không

Nếu bạn vượt qua { withCredentials: true }yêu cầu của mình, nó sẽ hoạt động.

Một cách tốt hơn sẽ là thiết lập withCredentialsnhư truetrongaxios.defaults

axios.defaults.withCredentials = true


5
Gửi thông tin đăng nhập với mọi yêu cầu là một việc làm không tốt. Các kiểm soát này có lý do. Nói chuyện với một dịch vụ khác, gửi tất cả cookie của bạn - cho dù chúng chưa được sử dụng, đã chín muồi để khai thác.
colm.anseo

2
@colminator chỉ những cookie có miền máy chủ làm miền của chúng mới được gửi. (Theo mặc định, chúng cũng sẽ không được gửi đến bất kỳ miền phụ nào và có thể được lọc thêm dựa trên đường dẫn.) Thực tế, chúng tôi chỉ gửi cookie máy chủ do máy chủ đặt.
M3RS

15

Tôi không quen thuộc với Axios, nhưng theo tôi biết trong javascript và ajax có một tùy chọn

withCredentials: true

Điều này sẽ tự động gửi cookie đến phía máy khách. Ví dụ: tình huống này cũng được tạo với passportjs, đặt cookie trên máy chủ


11

Điều quan trọng là đặt các tiêu đề cần thiết trong phản hồi nhanh. Đây là những thứ đã làm việc cho tôi:

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

Tôi bắt buộc phải thêm X-PINGOTHERvào Access-Control-Allow-Headers(Node.js 6.9 với Express 4.16, Chrome 63). Kiểm tra bài đăng của JakeElder về vấn đề GitHub này: github.com/axios/axios/issues/191#issuecomment-311069164
Frosty Z


5

cho mọi người vẫn không thể giải quyết nó, câu trả lời này đã giúp tôi. câu trả lời stackoverflow: 34558264

TLDR; một người cần đặt {withCredentials: true}trong cả yêu cầu GET cũng như yêu cầu POST (lấy cookie) cho cả axios cũng như tìm nạp.


1
Đây là điều tối quan trọng. Tôi đã bỏ qua điều này trong mã của mình và đã dành rất nhiều thời gian để tự hỏi tại sao { withCredentials: true }yêu cầu GET không có bất kỳ tác dụng nào.
yogmk

1
Vô cùng quan trọng! Có rất nhiều thảo luận về việc thêm withCredentials: truevào cấu hình yêu cầu nhưng không có chi tiết này. Tôi đã dành gần 2 ngày để cố gắng giải quyết vấn đề cho đến khi tôi bắt gặp điều này
R. Antao

4

Làm cách nào để Axios tự động gửi cookie theo yêu cầu?

bộ axios.defaults.withCredentials = true;

hoặc đối với một số yêu cầu cụ thể, bạn có thể sử dụng axios.get(url,{withCredentials:true})

điều này sẽ gây ra lỗi CORS nếu 'Access-Control-Allow-Origin' của bạn được đặt thành ký tự đại diện (*). Do đó, hãy đảm bảo chỉ định url xuất xứ của yêu cầu của bạn

ví dụ: nếu giao diện người dùng của bạn thực hiện yêu cầu chạy trên localhost: 3000, thì hãy đặt tiêu đề phản hồi là

res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');

cũng thiết lập

res.setHeader('Access-Control-Allow-Credentials',true);

3

Bạn có thể sử dụng withCredentialstài sản để chuyển cookie trong yêu cầu.

axios.get(`api_url`, { withCredentials: true })

Bằng cách thiết lập, { withCredentials: true }bạn có thể gặp phải vấn đề xuất xứ chéo. Để giải quyết điều đó bạn cần sử dụng

expressApp.use(cors({ credentials: true, origin: "http://localhost:8080" }));

Tại đây bạn có thể đọc về withCredentials


2

Bạn đang làm cho cả hai suy nghĩ lẫn lộn.

Bạn có "react-cookie" và "axios"

react-cookie => dùng để xử lý cookie ở phía máy khách

axios => là để gửi các yêu cầu ajax đến máy chủ

Với thông tin đó, nếu bạn muốn cookie từ phía máy khách cũng được giao tiếp ở phía phụ trợ, bạn sẽ cần kết nối chúng với nhau.

Lưu ý từ Readme "react-cookie":

Cookies isomorphic!

Để có thể truy cập cookie của người dùng trong khi kết xuất máy chủ, bạn có thể sử dụng plugToRequest hoặc setRawCookie.

liên kết đến readme

Nếu đây là những gì bạn cần, tuyệt vời.

Nếu không hãy comment để mình nói rõ hơn.


Không gì plugToRequestlàm chính xác? Tôi nghĩ để truy cập cookie trên máy chủ nút, tất cả những gì người ta cần là cookie-parserphần mềm trung gian (giả sử là Express)?
geoboy 27/09/17

2

Vì vậy, tôi đã gặp vấn đề chính xác này và mất khoảng 6 giờ đồng hồ tìm kiếm, tôi đã có

withCredentials: true

Nhưng trình duyệt vẫn không lưu cookie cho đến khi vì một số lý do kỳ lạ, tôi có ý tưởng xáo trộn cài đặt cấu hình:

Axios.post(GlobalVariables.API_URL + 'api/login', {
        email,
        password,
        honeyPot
    }, {
        withCredentials: true,
        headers: {'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'
    }});

Có vẻ như bạn nên gửi Khóa 'withCredentials' trước.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.