Come inviare l'autenticazione di base con axios


110

Sto cercando di implementare il seguente codice, ma qualcosa non funziona. Ecco il codice:

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

Restituisce un errore 401. Quando lo faccio con Postman c'è un'opzione per impostare l'autenticazione di base; se non riempio questi campi restituisce anche 401, ma se lo faccio la richiesta va a buon fine.

Qualche idea su cosa sto sbagliando?

Ecco una parte dei documenti dell'API su come implementare questo:

Questo servizio utilizza le informazioni di autenticazione di base nell'intestazione per stabilire una sessione utente. Le credenziali vengono convalidate rispetto al server. L'utilizzo di questo servizio web creerà una sessione con le credenziali utente passate e restituirà un JSESSIONID. Questo JSESSIONID può essere utilizzato nelle richieste successive per effettuare chiamate al servizio web. *

Risposte:


157

C'è un parametro "auth" per Basic Auth:

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

Fonte / Documenti: https://github.com/mzabriskie/axios

Esempio:

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

4
ciao, come posso impostarlo in tutte le chiamate axios? Devo aggiungere l'autenticazione di base a tutte le chiamate ajax. axios.defaults.auth = {nome utente: 'dd', password: '##'} non funziona per me.
hkg328


a proposito, puoi anche scrivere un involucro attorno agli assios per questo tipo di cose
luschn

Ho fatto un involucro per quello. ma
quell'API

1
@ hkg328 è necessario codificare la stringa username: password in base64 se si desidera impostare manualmente l'intestazione. qualcosa come import btoa da "btoa-lite"; token = btoa (nome utente + ':' + password); quindi imposta l'intestazione su "Base" + token;
shrumm

55

Il motivo per cui il codice nella tua domanda non si autentica è perché stai inviando l'autenticazione nell'oggetto dati, non nella configurazione, che lo inserirà nelle intestazioni. Secondo la documentazione di axios , l' alias del metodo di richiesta per postè:

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

Pertanto, affinché il codice funzioni, è necessario inviare un oggetto vuoto per i dati:

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

Lo stesso vale per l'utilizzo del parametro auth menzionato da @luschn. Il codice seguente è equivalente, ma utilizza invece il parametro auth (e passa anche un oggetto dati vuoto):

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
QUESTO
HA AIUTATO

1
Questa dovrebbe essere la risposta accettata. La risposta accettata è solo un duplicato della documentazione.
Barba

5

Per alcuni motivi, questo semplice problema sta bloccando molti sviluppatori. Ho lottato per molte ore con questa semplice cosa. Questo problema come molte dimensioni:

  1. CORS (se utilizzi un frontend e un backend su domini e porte differenti.
  2. Configurazione CORS backend
  3. Configurazione dell'autenticazione di base di Axios

CORS

La mia configurazione per lo sviluppo è con un'applicazione webpack vuejs in esecuzione su localhost: 8081 e un'applicazione di avvio a molla in esecuzione su localhost: 8080. Quindi, quando provo a chiamare l'API rest dal frontend, non è possibile che il browser mi consenta di ricevere una risposta dal backend di primavera senza le impostazioni CORS appropriate. CORS può essere utilizzato per rilassare la protezione Cross Domain Script (XSS) dei browser moderni. A quanto ho capito, i browser proteggono la tua SPA dall'attacco di un XSS. Ovviamente, alcune risposte su StackOverflow suggerivano di aggiungere un plug-in Chrome per disabilitare la protezione XSS, ma funziona davvero E se lo fosse, spingerebbe solo l'inevitabile problema per dopo.

Configurazione CORS backend

Ecco come dovresti configurare CORS nella tua app di avvio primaverile:

Aggiungere una classe CorsFilter per aggiungere le intestazioni appropriate nella risposta a una richiesta del client. Le intestazioni Access-Control-Allow-Origin e Access-Control-Allow sono la cosa più importante da avere per l'autenticazione di base.

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

    }
...
}

Aggiungi una classe di configurazione che estende Spring WebSecurityConfigurationAdapter. In questa classe inserirai il tuo filtro 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());
    }
...
}

Non è necessario inserire nulla relativo a CORS nel controller.

Fine frontale

Ora, nel frontend devi creare la tua query axios con l'intestazione di autorizzazione:

<!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>

Spero che questo ti aiuti.


noob CORS domanda, questo viene utilizzato solo nello sviluppo, giusto?
Len Joseph,

No, è anche e principalmente in produzione.
Erick Audet

3

Un esempio (axios_example.js) utilizzando Axios in 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);

Assicurati di fare nella directory del tuo progetto:

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

È quindi possibile testare l'API REST di Node.js utilizzando il browser all'indirizzo: http://localhost:5000/search?queryStr=xxxxxxxxx

Rif: https://github.com/axios/axios


3

La soluzione fornita da luschn e pillravi funziona bene a meno che non si riceva un'intestazione Strict-Transport-Security nella risposta.

L'aggiunta di withCredentials: true risolverà il problema.

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

1

Se stai tentando di eseguire l'autenticazione di base, puoi provare questo:

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}`
},
})

Questo ha funzionato per me. spero che aiuti

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.