วิธีส่ง Basic Auth ด้วย axios


118

ฉันกำลังพยายามติดตั้งโค้ดต่อไปนี้ แต่มีบางอย่างไม่ทำงาน นี่คือรหัส:

  var session_url = 'http://api_address/api/session_endpoint';
  var username = 'user';
  var password = 'password';
  var credentials = btoa(username + ':' + password);
  var basicAuth = 'Basic ' + credentials;
  axios.post(session_url, {
    headers: { 'Authorization': + basicAuth }
  }).then(function(response) {
    console.log('Authenticated');
  }).catch(function(error) {
    console.log('Error on Authentication');
  });

มันส่งคืนข้อผิดพลาด 401 เมื่อฉันทำกับบุรุษไปรษณีย์จะมีตัวเลือกในการตั้งค่าการตรวจสอบสิทธิ์ขั้นพื้นฐาน ถ้าฉันไม่กรอกฟิลด์เหล่านั้นมันก็จะส่งคืน 401 เช่นกัน แต่ถ้าฉันทำคำขอก็สำเร็จ

มีความคิดอะไรที่ฉันทำผิด?

นี่คือส่วนหนึ่งของเอกสารของ API เกี่ยวกับวิธีการใช้งานสิ่งนี้:

บริการนี้ใช้ข้อมูลการพิสูจน์ตัวตนพื้นฐานในส่วนหัวเพื่อสร้างเซสชันผู้ใช้ ข้อมูลรับรองถูกตรวจสอบกับเซิร์ฟเวอร์ การใช้บริการเว็บนี้จะสร้างเซสชันโดยส่งข้อมูลรับรองผู้ใช้และส่งคืน JSESSIONID JSESSIONID นี้สามารถใช้ในการร้องขอการโทรบริการเว็บในภายหลังได้ *

คำตอบ:


172

มีพารามิเตอร์ "auth" สำหรับ Basic Auth:

auth: {
  username: 'janedoe',
  password: 's00pers3cret'
}

ที่มา / เอกสาร: https://github.com/mzabriskie/axios

ตัวอย่าง:

await axios.post(session_url, {}, {
  auth: {
    username: uname,
    password: pass
  }
});

4
สวัสดีฉันจะตั้งค่านั้นในการโทร axios ทั้งหมดได้อย่างไร ฉันต้องการเพิ่มการรับรองความถูกต้องพื้นฐานในการโทรของ ajax ทั้งหมด axios.defaults.auth = {ชื่อผู้ใช้: 'dd', รหัสผ่าน: '##'} สิ่งนี้ใช้ไม่ได้สำหรับฉัน
hkg328


btw คุณสามารถเขียน wrapper รอบ axios สำหรับสิ่งเหล่านั้นได้
luschn

ฉันทำกระดาษห่อสำหรับสิ่งนั้น แต่ api นั้นทำให้ฉันมีข้อผิดพลาด 401
hkg328

1
@ hkg328 คุณต้องเข้ารหัสชื่อผู้ใช้สตริง: รหัสผ่านเป็น base64 หากคุณต้องการตั้งค่าส่วนหัวด้วยตนเอง บางอย่างเช่นนำเข้า btoa จาก 'btoa-lite'; โทเค็น = btoa (ชื่อผู้ใช้ + ':' + รหัสผ่าน); จากนั้นตั้งค่าส่วนหัวเป็น 'Basic' + token;
shrumm

59

สาเหตุที่รหัสในคำถามของคุณไม่รับรองความถูกต้องเนื่องจากคุณกำลังส่งการตรวจสอบสิทธิ์ในออบเจ็กต์ข้อมูลไม่ใช่ในการกำหนดค่าซึ่งจะใส่ไว้ในส่วนหัว ตามเอกสาร Axiosที่คำขอวิธีนามแฝงสำหรับpostเป็น:

axios.post (url [, data [, config]])

ดังนั้นเพื่อให้รหัสของคุณใช้งานได้คุณต้องส่งวัตถุว่างสำหรับข้อมูล:

var session_url = 'http://api_address/api/session_endpoint';
var username = 'user';
var password = 'password';
var basicAuth = 'Basic ' + btoa(username + ':' + password);
axios.post(session_url, {}, {
  headers: { 'Authorization': + basicAuth }
}).then(function(response) {
  console.log('Authenticated');
}).catch(function(error) {
  console.log('Error on Authentication');
});

เช่นเดียวกับการใช้พารามิเตอร์ auth ที่กล่าวถึงโดย @luschn รหัสต่อไปนี้เทียบเท่า แต่ใช้พารามิเตอร์ auth แทน (และยังส่งผ่านอ็อบเจ็กต์ข้อมูลว่าง):

var session_url = 'http://api_address/api/session_endpoint';
var uname = 'user';
var pass = 'password';
axios.post(session_url, {}, {
  auth: {
    username: uname,
    password: pass
  }
}).then(function(response) {
  console.log('Authenticated');
}).catch(function(error) {
  console.log('Error on Authentication');
});

1
ช่วยได้ขอบคุณ
superrcoop

1
นี่ควรเป็นคำตอบที่ได้รับการยอมรับ คำตอบที่ยอมรับเป็นเพียงเอกสารที่ซ้ำกัน
Sinister Beard

5

ด้วยเหตุผลบางประการปัญหาง่ายๆนี้คือการบล็อกนักพัฒนาจำนวนมาก ฉันต่อสู้กับสิ่งง่ายๆนี้มาหลายชั่วโมง ปัญหานี้มีหลายมิติ:

  1. CORS (หากคุณใช้ส่วนหน้าและแบ็กเอนด์บนโดเมนและพอร์ตต่างๆ
  2. การกำหนดค่าแบ็กเอนด์ CORS
  3. การกำหนดค่าการพิสูจน์ตัวตนพื้นฐานของ Axios

CORS

การตั้งค่าของฉันสำหรับการพัฒนาคือแอปพลิเคชัน vuejs webpack ที่ทำงานบน localhost: 8081 และแอปพลิเคชัน spring boot ที่ทำงานบน localhost: 8080 ดังนั้นเมื่อพยายามเรียก API ส่วนที่เหลือจากส่วนหน้าไม่มีทางที่เบราว์เซอร์จะให้ฉันได้รับการตอบกลับจากแบ็กเอนด์สปริงโดยไม่มีการตั้งค่า CORS ที่เหมาะสม CORS สามารถใช้เพื่อผ่อนคลายการป้องกัน Cross Domain Script (XSS) ที่เบราว์เซอร์รุ่นใหม่มี ตามที่ฉันเข้าใจแล้วเบราว์เซอร์กำลังปกป้อง SPA ของคุณจากการถูกโจมตีโดย XSS แน่นอนคำตอบบางอย่างใน StackOverflow แนะนำให้เพิ่มปลั๊กอิน Chrome เพื่อปิดใช้งานการป้องกัน XSS แต่วิธีนี้ใช้งานได้จริงและถ้าเป็นเช่นนั้นจะผลักปัญหาที่หลีกเลี่ยงไม่ได้ในภายหลังเท่านั้น

การกำหนดค่าแบ็กเอนด์ CORS

นี่คือวิธีที่คุณควรตั้งค่า CORS ในแอพ spring boot ของคุณ:

เพิ่มคลาส CorsFilter เพื่อเพิ่มส่วนหัวที่เหมาะสมในการตอบสนองคำขอของไคลเอ็นต์ Access-Control-Allow-Origin และ Access-Control-Allow-Headers เป็นสิ่งสำคัญที่สุดที่ต้องมีสำหรับการพิสูจน์ตัวตนขั้นพื้นฐาน

    public class CorsFilter implements Filter {

...
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        response.setHeader("Access-Control-Allow-Origin", "http://localhost:8081");
        response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
        **response.setHeader("Access-Control-Allow-Headers", "authorization, Content-Type");**
        response.setHeader("Access-Control-Max-Age", "3600");

        filterChain.doFilter(servletRequest, servletResponse);

    }
...
}

เพิ่มคลาสคอนฟิกูเรชันซึ่งขยาย Spring WebSecurityConfigurationAdapter ในคลาสนี้คุณจะฉีดตัวกรอง CORS ของคุณ:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
    @Bean
    CorsFilter corsFilter() {
        CorsFilter filter = new CorsFilter();
        return filter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.addFilterBefore(corsFilter(), SessionManagementFilter.class) //adds your custom CorsFilter
          .csrf()
          .disable()
          .authorizeRequests()
          .antMatchers("/api/login")
          .permitAll()
          .anyRequest()
          .authenticated()
          .and()
          .httpBasic()
          .authenticationEntryPoint(authenticationEntryPoint)
          .and()
          .authenticationProvider(getProvider());
    }
...
}

คุณไม่ต้องใส่อะไรที่เกี่ยวข้องกับ CORS ในคอนโทรลเลอร์ของคุณ

ส่วนหน้า

ตอนนี้ในส่วนหน้าคุณต้องสร้างแบบสอบถามแกนของคุณด้วยส่วนหัวการอนุญาต:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
    <p>{{ status }}</p>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            status: ''
        },
        created: function () {
            this.getBackendResource();
        },
        methods: {
            getBackendResource: function () {
                this.status = 'Loading...';
                var vm = this;
                var user = "aUserName";
                var pass = "aPassword";
                var url = 'http://localhost:8080/api/resource';

                var authorizationBasic = window.btoa(user + ':' + pass);
                var config = {
                    "headers": {
                        "Authorization": "Basic " + authorizationBasic
                    }
                };
                axios.get(url, config)
                    .then(function (response) {
                        vm.status = response.data[0];
                    })
                    .catch(function (error) {
                        vm.status = 'An error occured.' + error;
                    })
            }
        }
    })
</script>
</body>
</html>

หวังว่านี่จะช่วยได้


คำถาม noob CORS นี่ใช้ในการพัฒนาเท่านั้นใช่ไหม?
Len Joseph

ไม่เป็นเช่นกันและส่วนใหญ่อยู่ในการผลิต
Erick Audet

4

โซลูชันที่กำหนดโดย luschn และ pillravi ทำงานได้ดีเว้นแต่คุณจะได้รับส่วนหัวStrict-Transport-Securityในการตอบกลับ

การเพิ่มwithCredentials: trueจะช่วยแก้ปัญหานั้นได้

  axios.post(session_url, {
    withCredentials: true,
    headers: {
      "Accept": "application/json",
      "Content-Type": "application/json"
    }
  },{
    auth: {
      username: "USERNAME",
      password: "PASSWORD"
  }}).then(function(response) {
    console.log('Authenticated');
  }).catch(function(error) {
    console.log('Error on Authentication');
  });

3

ตัวอย่าง (axios_example.js) โดยใช้ Axios ใน Node.js:

const axios = require('axios');
const express = require('express');
const app = express();
const port = process.env.PORT || 5000;

app.get('/search', function(req, res) {
    let query = req.query.queryStr;
    let url = `https://your.service.org?query=${query}`;

    axios({
        method:'get',
        url,
        auth: {
            username: 'xxxxxxxxxxxxx',
            password: 'xxxxxxxxxxxxx'
        }
    })
    .then(function (response) {
        res.send(JSON.stringify(response.data));
    })
    .catch(function (error) {
        console.log(error);
    });
});

var server = app.listen(port);

ตรวจสอบให้แน่ใจในไดเรกทอรีโครงการของคุณที่คุณทำ:

npm init
npm install express
npm install axios
node axios_example.js

จากนั้นคุณสามารถทดสอบ Node.js REST API โดยใช้เบราว์เซอร์ของคุณได้ที่: http://localhost:5000/search?queryStr=xxxxxxxxx

อ้างอิง: https://github.com/axios/axios


2

หากคุณกำลังพยายามตรวจสอบสิทธิ์ขั้นพื้นฐานคุณสามารถลองทำสิ่งนี้:

const username = ''
const password = ''

const token = Buffer.from(`${username}:${password}`, 'utf8').toString('base64')

const url = 'https://...'
const data = {
...
}

axios.post(url, data, {
  headers: {
 'Authorization': `Basic ${token}`
},
})

สิ่งนี้ได้ผลสำหรับฉัน หวังว่าจะช่วยได้

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