วิธีส่งส่วนหัวการอนุญาตด้วย axios


99

ฉันจะส่งส่วนหัวการตรวจสอบความถูกต้องด้วยโทเค็นผ่าน axios.js ได้อย่างไร ฉันได้ลองทำบางอย่างแล้วไม่ประสบความสำเร็จเช่น:

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

ทำให้ฉันมีข้อผิดพลาดนี้:

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

ฉันจัดการเพื่อให้มันทำงานได้โดยการตั้งค่าเริ่มต้นทั่วโลก แต่ฉันเดาว่านี่ไม่ใช่ความคิดที่ดีที่สุดสำหรับคำขอเดียว

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

อัปเดต:

คำตอบของโคลช่วยให้ฉันพบปัญหา ฉันใช้มิดเดิลแวร์ django-cors-headersซึ่งจัดการส่วนหัวการอนุญาตตามค่าเริ่มต้นแล้ว

แต่ฉันสามารถเข้าใจข้อความแสดงข้อผิดพลาดและแก้ไขข้อผิดพลาดในรหัสคำขอ axios ของฉันซึ่งควรมีลักษณะดังนี้

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

คำตอบ:


89

เมื่อวันที่ http ไม่ใช่ง่ายขอเบราว์เซอร์ของคุณจะส่ง "preflight" คำขอ (คำขอวิธี OPTIONS) ก่อนเพื่อตรวจสอบว่าเว็บไซต์ในคำถามที่จะพิจารณาข้อมูลที่ปลอดภัยในการส่ง (ดูที่นี่สำหรับข้อมูลจำเพาะนโยบายข้ามกำเนิดเกี่ยวกับเรื่องนี้) หนึ่งในส่วนหัวที่เกี่ยวข้องที่โฮสต์สามารถตั้งค่าในการตอบสนอง preflight Access-Control-Allow-Headersคือ หากส่วนหัวใด ๆ ที่คุณต้องการส่งไม่มีอยู่ในรายการของส่วนหัวที่อนุญาตพิเศษของข้อกำหนดหรือการตอบสนองของเซิร์ฟเวอร์ล่วงหน้าเบราว์เซอร์จะปฏิเสธที่จะส่งคำขอของคุณ

ในกรณีของคุณคุณกำลังพยายามส่งAuthorizationส่วนหัวซึ่งไม่ถือว่าเป็นส่วนหัวที่ปลอดภัยในระดับสากลในการส่ง จากนั้นเบราว์เซอร์จะส่งคำขอ preflight เพื่อถามเซิร์ฟเวอร์ว่าควรส่งส่วนหัวนั้นหรือไม่ เซิร์ฟเวอร์กำลังส่งAccess-Control-Allow-Headersส่วนหัวที่ว่างเปล่า(ซึ่งถือว่าหมายถึง "ไม่อนุญาตให้มีส่วนหัวเพิ่มเติมใด ๆ ") หรือกำลังส่งส่วนหัวที่ไม่รวมAuthorizationอยู่ในรายการส่วนหัวที่อนุญาต ด้วยเหตุนี้เบราว์เซอร์จึงไม่ส่งคำขอของคุณและเลือกที่จะแจ้งให้คุณทราบโดยการแสดงข้อผิดพลาดแทน

วิธีแก้ปัญหา Javascript ใด ๆ ที่คุณพบซึ่งช่วยให้คุณสามารถส่งคำขอนี้ได้ทุกครั้งควรได้รับการพิจารณาว่าเป็นจุดบกพร่องเนื่องจากขัดต่อนโยบายการร้องขอข้ามแหล่งที่มาที่เบราว์เซอร์ของคุณพยายามบังคับใช้เพื่อความปลอดภัยของคุณเอง

tl; dr - หากคุณต้องการส่งAuthorizationส่วนหัวเซิร์ฟเวอร์ของคุณได้รับการกำหนดค่าให้ดีขึ้นเพื่ออนุญาต ตั้งค่าเซิร์ฟเวอร์ของคุณเพื่อให้ตอบสนองต่อOPTIONSคำขอที่ url นั้นด้วยAccess-Control-Allow-Headers: Authorizationส่วนหัว


11
ขอบคุณโคล! คำตอบของคุณช่วยให้ฉันพบปัญหา ฉันใช้มิดเดิลแวร์ django-cors-headers ซึ่งจัดการส่วนหัวการอนุญาตตามค่าเริ่มต้นแล้ว แต่ฉันสามารถเข้าใจข้อความแสดงข้อผิดพลาดและแก้ไขข้อผิดพลาดในรหัสคำขอ axios ของฉันซึ่งควรมีลักษณะเช่นนี้ return axios.get(URLConstants.USER_URL, { headers: { Authorization: `Bearer ${data.token}` } });
foobar

1
ยินดีต้อนรับ! ฉันพบปัญหาประเภทนี้กับ API ของฉันตลอดเวลา ดีใจที่ได้ช่วยให้คุณเข้าใจกระบวนการที่ต้องดำเนินการ
Cole Erickson

44

ลองสิ่งนี้:

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

1
ดังนั้นชื่อส่วนหัวจะเป็น "Access-Control-Allow-Headers" และค่าคือสิ่งที่คุณต้องการ
Matija Župančić

คุณหมายความว่าฉันมีบางอย่างเช่น: axios.get (url, {headers: {'Access-Control-Allow-Headers': 'Bearer <my token>'}})? ไม่ได้ผล
foobar

11
ฉันเชื่อว่าควรเป็น {'Authorization': 'Bearer <my token>'}
John Harding

38

สิ่งนี้ได้ผลสำหรับฉัน:

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

2
มีรายละเอียดน้อยกว่าในคำตอบเมื่อเทียบกับข้างต้น แต่นี่คือคำตอบที่ทุกคนมองหาเมื่อค้นหาใน Google
Black Mamba

33

แทนที่จะเพิ่มลงในทุกคำขอคุณสามารถเพิ่มเป็นค่ากำหนดเริ่มต้นได้เช่นนั้น

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

คุณวางโครงแบบนี้ได้อย่างไร? ในรูท (index.js, App.js)? หรือในไฟล์แยกกัน?
ibubi

8

คุณเกือบถูกต้องแล้วเพียงแค่ปรับรหัสของคุณด้วยวิธีนี้

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

สังเกตว่าฉันวางแบ็คทิกไว้ที่ใดฉันเพิ่ม '' หลังผู้ถือคุณสามารถละเว้นได้หากแน่ใจว่าจะจัดการที่ฝั่งเซิร์ฟเวอร์


6
โดยปกติ (ตามข้อมูลจำเพาะ) จะมีช่องว่างไม่ใช่เส้นประ ( -) ระหว่างโครงร่างการตรวจสอบสิทธิ์และโทเค็น ฉันไม่เคยเห็นเซิร์ฟเวอร์ประเภทใดต้องการเส้นประดังที่คุณแสดงและส่วนใหญ่ถ้าไม่ใช่ทั้งหมดจะส่งข้อผิดพลาดกลับมาหากมี
รามัน

6

แทนที่จะเรียกใช้ฟังก์ชัน axios.get ใช้:

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

1

คุณสามารถลองสิ่งนี้

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

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: คุณต้องเพิ่ม OPTIONS & Authorization ให้กับ setHeader ()

การเปลี่ยนแปลงนี้แก้ไขปัญหาของฉันได้แล้วลองดูสิ!


0

ติดตั้งcorsมิดเดิลแวร์ เราพยายามแก้ไขด้วยรหัสของเราเอง แต่ความพยายามทั้งหมดล้มเหลวอย่างน่าอนาถ

สิ่งนี้ทำให้มันใช้งานได้:

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

ลิงค์ต้นฉบับ


1
นี่คือเซิร์ฟเวอร์โหนดไม่ใช่สำหรับ axios
Marc Garcia

ผู้ใช้ที่พบคำถามนี้จะพบว่าคำตอบนี้มีประโยชน์ คำถามนี้สามารถใช้สำหรับการทำงานกับเซิร์ฟเวอร์โหนดในกรณีการใช้งานและเป็นเครื่องเตือนความจำที่คอร์สามารถแก้ไขปัญหาได้หรือเพื่อย้ายการตรวจสอบส่วนหัวแบ็กเอนด์ด้านล่างโค้ดด้านบน ช่วยให้ฉันหายหงุดหงิดมากขอบคุณเสียงระฆัง
DORRITO
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.