Як надіслати Basic Auth з axios


107

Я намагаюся реалізувати наступний код, але щось не працює. Ось код:

  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. Коли я роблю це з Поштовиком, є можливість встановити Basic Auth; якщо я не заповнюю ці поля, він також повертає 401, але якщо я це роблю, запит успішний.

Будь-які ідеї, що я роблю не так?

Ось частина документів API про те, як це реалізувати:

Ця служба використовує базову інформацію про автентифікацію в заголовку для встановлення сеансу користувача. Повноваження перевіряються на сервері. Використання цієї веб-служби створить сеанс із переданими обліковими даними користувача та поверне JSESSIONID. Цей JSESSIONID можна використовувати в наступних запитах для здійснення дзвінків через веб-сервіс. *

Відповіді:


153

Існує параметр "auth" для Basic Auth:

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

Джерело / Документи: https://github.com/mzabriskie/axios

Приклад:

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

4
привіт, як я можу встановити це у всіх викликах аксіо? Мені потрібно додати Basic auth для всіх викликів ajax. axios.defaults.auth = {ім'я користувача: 'dd', пароль: '##'} це у мене не працює.
hkg328

можливо, це допомагає: gist.github.com/EQuimper/dc5fe02dcaca4469091729e1313f78d1
luschn

До речі, ти можеш також написати обгортку навколо аксіосу для таких речей
luschn

Я зробив обгортку для цього. але цей api видає мені помилку 401
hkg328

1
@ hkg328 вам потрібно закодувати рядок username: password до base64, якщо ви хочете вручну встановити заголовок. щось на зразок імпорту btoa з 'btoa-lite'; маркер = btoa (ім'я користувача + ':' + пароль); потім встановіть заголовок на 'Basic' + маркер;
шрамм

54

Причина, по якій код у вашому запитанні не проходить автентифікацію, полягає в тому, що ви надсилаєте аутентифікацію в об’єкт даних, а не в конфігурацію, яка помістить його в заголовки. Відповідно до axios docs , псевдонім методу запиту для 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
Це має бути прийнятою відповіддю. Прийнята відповідь - це лише дублікат документації.
Зловісна борода

5

З деяких причин ця проста проблема блокує багатьох розробників. Я багато годин боровся з цією простою справою. У цій проблемі стільки вимірів:

  1. CORS (якщо ви використовуєте інтерфейс і бекенд на різних доменах та портах.
  2. Конфігурація вихідного CORS
  3. Базова конфігурація автентифікації Axios

CORS

Моє налаштування для розробки - це програма vuejs webpack, запущена на localhost: 8081, та програма для весняного завантаження, що працює на localhost: 8080. Отже, намагаючись викликати rest інтерфейс з інтерфейсу, браузер не має можливості дозволити мені отримати відповідь від весняної серверної системи без належних налаштувань CORS. CORS може бути використаний для розслаблення захисту міждоменного сценарію (XSS), який має сучасний браузер. Як я розумію, браузери захищають ваш SPA від атаки XSS. Звичайно, деякі відповіді на StackOverflow пропонували додати chrome-плагін, щоб вимкнути захист XSS, але це дійсно працює, І якби це було так, це лише сунуло б неминучу проблему на потім.

Конфігурація вихідного CORS

Ось як слід налаштувати CORS у вашому додатку для весняного завантаження:

Додайте клас 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.

Фронтенд

Тепер у фронтенді вам потрібно створити запит axios за допомогою заголовка Authorization:

<!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 питання, це використовується лише для розробки, так?
Лен Джозеф

Ні, це також і в основному на виробництві.
Ерік

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

Потім ви можете протестувати API NEST.js REST за допомогою свого браузера за адресою: http://localhost:5000/search?queryStr=xxxxxxxxx

Посилання: https://github.com/axios/axios


3

Рішення, надане luschn та pillravi, чудово працює, якщо ви не отримаєте суворий транспортний захист заголовок .

Додавання 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');
  });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.