Jak wysłać Basic Auth z axios


109

Próbuję zaimplementować następujący kod, ale coś nie działa. Oto kod:

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

Zwraca błąd 401. Kiedy robię to z Postmanem, jest opcja ustawienia podstawowego uwierzytelniania; jeśli nie wypełnię tych pól, zwraca również 401, ale jeśli to zrobię, żądanie się powiedzie.

Jakieś pomysły, co robię źle?

Oto część dokumentacji API, jak to zaimplementować:

Ta usługa używa informacji o podstawowym uwierzytelnieniu w nagłówku do ustanowienia sesji użytkownika. Poświadczenia są sprawdzane na serwerze. Użycie tej usługi internetowej utworzy sesję z przekazanymi poświadczeniami użytkownika i zwróci JSESSIONID. Ten identyfikator JSESSIONID może być używany w kolejnych żądaniach wywołań usług internetowych. *

Odpowiedzi:


155

Istnieje parametr „auth” dla podstawowego uwierzytelniania:

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

Źródło / Dokumenty: https://github.com/mzabriskie/axios

Przykład:

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

4
cześć, jak mogę to ustawić we wszystkich wywołaniach axios? Muszę dodać podstawowe uwierzytelnianie do wszystkich wywołań ajax. axios.defaults.auth = {nazwa użytkownika: 'dd', hasło: '##'} to nie działa dla mnie.
hkg328


przy okazji, możesz też napisać opakowanie wokół axiosów na takie rzeczy
luschn,

Zrobiłem na to opakowanie. ale ten interfejs API daje mi błąd 401
hkg328

1
@ hkg328 musisz zakodować ciąg nazwa_użytkownika: hasło do base64, jeśli chcesz ręcznie ustawić nagłówek. coś w rodzaju import btoa z „btoa-lite”; token = btoa (nazwa użytkownika + ':' + hasło); następnie ustaw nagłówek na „Basic” + token;
krewetka

54

Powodem, dla którego kod w twoim pytaniu nie jest uwierzytelniany, jest to, że wysyłasz autoryzację w obiekcie danych, a nie w konfiguracji, która umieści ją w nagłówkach. Za tych docs Axios The prośba metoda alias na postto:

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

Dlatego, aby Twój kod działał, musisz wysłać pusty obiekt na dane:

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

To samo dotyczy używania parametru auth wspomnianego przez @luschn. Poniższy kod jest równoważny, ale zamiast tego używa parametru auth (a także przekazuje pusty obiekt danych):

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
TO POMOGŁO, DZIĘKI
superrcoop

1
To powinna być akceptowana odpowiedź. Zaakceptowana odpowiedź to tylko kopia dokumentacji.
Sinister Beard

5

Z pewnych powodów ten prosty problem blokuje wielu programistów. Przez wiele godzin walczyłem z tą prostą rzeczą. Ten problem w wielu wymiarach:

  1. CORS (jeśli używasz frontendu i backendu na różnych domenach i portach.
  2. Konfiguracja CORS zaplecza
  3. Podstawowa konfiguracja uwierzytelniania Axios

CORS

Moja konfiguracja do programowania obejmuje aplikację vuejs webpack działającą na hoście lokalnym: 8081 i aplikację rozruchową wiosną działającą na hoście lokalnym: 8080. Więc kiedy próbuję wywołać rest API z frontendu, nie ma możliwości, żeby przeglądarka pozwoliła mi otrzymać odpowiedź z backendu sprężynowego bez odpowiednich ustawień CORS. CORS może służyć do złagodzenia ochrony skryptów międzydomenowych (XSS), które mają nowoczesne przeglądarki. Jak rozumiem, przeglądarki chronią Twoje SPA przed atakiem XSS. Oczywiście niektóre odpowiedzi na StackOverflow sugerowały dodanie wtyczki Chrome w celu wyłączenia ochrony XSS, ale to naprawdę działa, a gdyby tak było, tylko popchnęłoby nieunikniony problem na później.

Konfiguracja CORS zaplecza

Oto, jak należy skonfigurować CORS w aplikacji do rozruchu wiosennego:

Dodaj klasę CorsFilter, aby dodać odpowiednie nagłówki w odpowiedzi na żądanie klienta. Access-Control-Allow-Origin i Access-Control-Allow-Headers to najważniejsze elementy podstawowego uwierzytelniania.

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

    }
...
}

Dodaj klasę konfiguracji, która rozszerza Spring WebSecurityConfigurationAdapter. W tej klasie wstrzykniesz swój filtr 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());
    }
...
}

Nie musisz umieszczać niczego związanego z CORS w swoim kontrolerze.

Frontend

Teraz w interfejsie musisz utworzyć zapytanie Axios z nagłówkiem 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>

Mam nadzieję że to pomoże.


noob CORS pytanie, to jest używane tylko w programowaniu, prawda?
Len Joseph

Nie, jest również i głównie w produkcji.
Erick Audet

3

Przykład (axios_example.js) przy użyciu Axios w 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);

Upewnij się, że w katalogu projektu robisz:

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

Następnie możesz przetestować interfejs REST API Node.js za pomocą przeglądarki pod adresem: http://localhost:5000/search?queryStr=xxxxxxxxx

Ref: https://github.com/axios/axios


3

Rozwiązanie podane przez luschn i pillravi działa dobrze, chyba że w odpowiedzi otrzymasz nagłówek Strict-Transport-Security .

Dodanie withCredentials: true rozwiąże ten problem.

  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');
  });
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.