Cách gửi tiêu đề ủy quyền với axios


96

Làm cách nào để gửi tiêu đề xác thực bằng mã thông báo qua axios.js? Tôi đã thử một vài điều mà không thành công, ví dụ:

const header = `Authorization: Bearer ${token}`;
return axios.get(URLConstants.USER_URL, { headers: { header } });

Cho tôi lỗi này:

XMLHttpRequest cannot load http://localhost:8000/accounts/user/. Request header field header is not allowed by Access-Control-Allow-Headers in preflight response.

Tôi đã quản lý để nó hoạt động bằng cách đặt mặc định chung, nhưng tôi đoán đây không phải là ý tưởng tốt nhất cho một yêu cầu:

axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;

Cập nhật:

Câu trả lời của Cole đã giúp tôi tìm ra vấn đề. Tôi đang sử dụng phần mềm trung gian django-cors-headers, phần mềm này đã xử lý tiêu đề ủy quyền theo mặc định.

Nhưng tôi có thể hiểu thông báo lỗi và đã sửa lỗi trong mã yêu cầu axios của mình, mã này sẽ giống như thế này

return axios.get(URLConstants.USER_URL, { headers: { Authorization: `Bearer ${data.token}` } });

Câu trả lời:


87

Đối với các yêu cầu http không đơn giản, trình duyệt của bạn sẽ gửi một yêu cầu "preflight" (yêu cầu phương thức TÙY CHỌN) trước để xác định những gì trang web được đề cập cho là thông tin an toàn để gửi (xem tại đây để biết thông số kỹ thuật về chính sách nguồn gốc chéo về điều này). Một trong những tiêu đề có liên quan mà máy chủ có thể đặt trong phản hồi preflight là Access-Control-Allow-Headers. Nếu bất kỳ tiêu đề nào bạn muốn gửi không được liệt kê trong danh sách tiêu đề được liệt kê trong danh sách trắng của thông số kỹ thuật hoặc phản hồi preflight của máy chủ, thì trình duyệt sẽ từ chối gửi yêu cầu của bạn.

Trong trường hợp của bạn, bạn đang cố gắng gửi một Authorizationtiêu đề, tiêu đề này không được coi là một trong những cách gửi tiêu đề an toàn. Sau đó, trình duyệt sẽ gửi một yêu cầu preflight để hỏi máy chủ có nên gửi tiêu đề đó hay không. Máy chủ đang gửi một Access-Control-Allow-Headerstiêu đề trống (được coi là "không cho phép thêm bất kỳ tiêu đề nào") hoặc nó đang gửi một tiêu đề không có Authorizationtrong danh sách các tiêu đề được phép của nó. Do đó, trình duyệt sẽ không gửi yêu cầu của bạn và thay vào đó chọn thông báo cho bạn bằng cách thông báo lỗi.

Bất kỳ giải pháp Javascript nào mà bạn thấy cho phép bạn gửi yêu cầu này dù sao cũng phải được coi là lỗi vì nó đi ngược lại chính sách yêu cầu nguồn gốc chéo mà trình duyệt của bạn đang cố gắng thực thi vì sự an toàn của chính bạn.

tl; dr - Nếu bạn muốn gửiAuthorizationtiêu đề, máy chủ của bạn tốt hơn nên được định cấu hình để cho phép nó. Thiết lập máy chủ của bạn để nó phản hồi mộtOPTIONSyêu cầu tại url đó bằngAccess-Control-Allow-Headers: Authorizationtiêu đề.


11
Cảm ơn, Cole! Câu trả lời của bạn đã giúp tôi tìm ra vấn đề. Tôi đang sử dụng phần mềm trung gian django-cors-headers, phần mềm này đã xử lý tiêu đề ủy quyền theo mặc định. Nhưng tôi đã có thể hiểu được thông báo lỗi và cố định một lỗi trong mã yêu cầu Axios của tôi, mà sẽ trông như thế này return axios.get(URLConstants.USER_URL, { headers: { Authorization: `Bearer ${data.token}` } });
foobar

1
Không có gì! Tôi luôn gặp phải loại vấn đề này với các API của mình. Rất vui vì tôi có thể giúp bạn hiểu quá trình nó phải trải qua.
Cole Erickson

43

Thử cái này :

axios.get(
    url,
    {headers: {
        "name" : "value"
      }
    }
  )
  .then((response) => {
      var response = response.data;
    },
    (error) => {
      var status = error.response.status
    }
  );

1
Vì vậy, tên tiêu đề sẽ là 'Access-Control-Allow-Headers' và giá trị là những gì bạn muốn.
Matija Župančić

Vậy, ý bạn là tôi muốn có một cái gì đó như: axios.get (url, {headers: {'Access-Control-Allow-Headers': 'Bearer <my token>'}})? Điều đó không hiệu quả.
foobar,

11
Tôi tin rằng nó phải là {'Authorization': 'Bearer <mã thông báo của tôi>'}
John Harding

35

Điều này đã làm việc cho tôi:

let webApiUrl = 'example.com/getStuff';
let tokenStr = 'xxyyzz';
axios.get(webApiUrl, { headers: {"Authorization" : `Bearer ${tokenStr}`} });

Có ít chi tiết hơn trong câu trả lời so với phần trên nhưng đây là câu trả lời mà mọi người đều tìm kiếm khi họ tìm kiếm trên google.
Black Mamba

32

Thay vì thêm nó vào mọi yêu cầu, bạn chỉ có thể thêm nó làm cấu hình mặc định như vậy.

axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}` 

làm thế nào để bạn đặt cấu hình này? trong thư mục gốc (index.js, App.js)? Hay trong một tệp riêng biệt?
ibubi

8

Bạn gần đúng, chỉ cần điều chỉnh mã của bạn theo cách này

const headers = { Authorization: `Bearer ${token}` };
return axios.get(URLConstants.USER_URL, { headers });

lưu ý nơi tôi đặt các dấu gạch ngược, tôi đã thêm '' sau Dấu hiệu, bạn có thể bỏ qua nếu bạn chắc chắn sẽ xử lý ở phía máy chủ


6
Thông thường (theo thông số) có một khoảng trắng, không phải dấu gạch ngang ( -), giữa lược đồ xác thực và mã thông báo. Tôi chưa bao giờ thấy bất kỳ loại máy chủ nào yêu cầu dấu gạch ngang như bạn đã trình bày và hầu hết nếu không, tất cả sẽ gửi lại lỗi nếu được cung cấp.
Raman

6

Thay vì gọi hàm axios.get Sử dụng:

axios({ method: 'get', url: 'your URL', headers: { Authorization: `Bearer ${token}` } })

0
res.setHeader('Access-Control-Allow-Headers',
            'Access-Control-Allow-Headers, Origin,OPTIONS,Accept,Authorization, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers');

Blockquote: bạn phải thêm TÙY CHỌN & Ủy quyền vào setHeader ()

thay đổi này đã khắc phục sự cố của tôi, chỉ cần thử!


0

Cài đặt corsphần mềm trung gian. Chúng tôi đã cố gắng giải nó bằng mã của riêng mình, nhưng mọi nỗ lực đều thất bại thảm hại.

Điều này làm cho nó hoạt động:

cors = require('cors')
app.use(cors());

Liên kết gốc


điều này dành cho các máy chủ nút, không phải cho axios
Marc Garcia

Người dùng tìm thấy câu hỏi này có thể thấy câu trả lời này hữu ích. Câu hỏi này có thể được sử dụng để làm việc với các máy chủ nút trong các trường hợp sử dụng và là một lời nhắc nhở rằng các bộ mã có thể giải quyết vấn đề của họ hoặc để di chuyển kiểm tra tiêu đề phụ trợ của họ bên dưới mã trên. Đã giúp đỡ tôi rất nhiều thất vọng, Cảm ơn bạn đã rung chuông.
DORRITO

0

Bạn có thể thử điều này.

axios.get(
    url,
    {headers: {
            "Access-Control-Allow-Origin" : "*",
            "Content-type": "Application/json",
            "Authorization": `Bearer ${your-token}`
            }   
        }
  )
  .then((response) => {
      var response = response.data;
    },
    (error) => {
      var status = error.response.status
    }
  );
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.