271 votes

Comment envoyer une Auth de base avec axios

J'essaie de mettre en œuvre le code suivant, mais quelque chose ne fonctionne pas. Voici le code :

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

Il renvoie une erreur 401. Lorsque je le fais avec Postman, il y a une option pour définir l'authentification de base ; si je ne remplis pas ces champs, il renvoie également une erreur 401, mais si je le fais, la demande est réussie.

Une idée de ce que je fais mal ?

Voici une partie de la documentation de l'API qui explique comment mettre en œuvre cette méthode :

Ce service utilise les informations d'authentification de base dans l'en-tête pour établir une session utilisateur. Les informations d'identification sont validées par le serveur. L'utilisation de ce service web créera une session avec les informations d'identification de l'utilisateur transmises et renverra un JSESSIONID. Ce JSESSIONID peut être utilisé dans les requêtes suivantes pour effectuer des appels de service Web.

395voto

luschn Points 6092

Il existe un paramètre "auth" pour l'authentification de base :

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

Source/Docs : https://github.com/mzabriskie/axios

8 votes

Bonjour, comment puis-je définir cela dans tous les appels axios ? J'ai besoin d'ajouter une authentification de base à tous les appels ajax. axios.defaults.auth = { username : 'dd', password : '##'} cela ne fonctionne pas pour moi.

0 votes

0 votes

En fait, vous pouvez aussi écrire un wrapper autour d'axios pour ce genre de choses.

108voto

pillravi Points 2413

La raison pour laquelle le code dans votre question n'authentifie pas est que vous envoyez l'authentification dans l'objet de données, et non dans la configuration, qui la mettra dans les en-têtes. Selon la norme docs axios le alias de la méthode de demande pour post est :

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

Par conséquent, pour que votre code fonctionne, vous devez envoyer un objet vide pour les données :

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

Il en va de même pour l'utilisation du paramètre auth mentionné par @luschn. Le code suivant est équivalent, mais utilise le paramètre auth à la place (et passe également un objet de données vide) :

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

2 votes

CELA A AIDÉ, MERCI

2 votes

Cela devrait être la réponse acceptée. La réponse acceptée est juste un duplicata de la documentation.

0 votes

Pas besoin de cela en novembre 2020 : github.com/axios/axios#axiosrequestconfigdG9tbzp0b21vOTgy

13voto

Erick Audet Points 75

Pour certaines raisons, ce problème simple bloque de nombreux développeurs. J'ai lutté pendant de nombreuses heures avec cette simple chose. Ce problème a plusieurs dimensions :

  1. CORS (si vous utilisez un frontend et un backend sur différents domaines et ports.
  2. Configuration CORS du backend
  3. Configuration de l'authentification de base d'Axios

CORS

Ma configuration pour le développement est avec une application vuejs webpack fonctionnant sur localhost:8081 et une application spring boot fonctionnant sur localhost:8080. Ainsi, lorsque j'essaie d'appeler l'API de repos depuis le front-end, il n'y a aucune chance que le navigateur me laisse recevoir une réponse du back-end de Spring sans les paramètres CORS appropriés. CORS peut être utilisé pour relâcher la protection Cross Domain script (XSS) que les navigateurs modernes ont. Si je comprends bien, les navigateurs protègent votre SPA contre une attaque par un XSS. Bien sûr, certaines réponses sur StackOverflow suggèrent d'ajouter un plugin chrome pour désactiver la protection XSS mais cela ne fonctionne pas vraiment ET si c'était le cas, cela ne ferait que repousser l'inévitable problème à plus tard.

Configuration CORS du backend

Voici comment vous devez configurer CORS dans votre application Spring Boot :

Ajouter une classe CorsFilter pour ajouter les en-têtes appropriés dans la réponse à une demande du client. Access-Control-Allow-Origin et Access-Control-Allow-Headers sont les éléments les plus importants à avoir pour l'authentification de 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);

    }
...
}

Ajouter une classe de configuration qui étend Spring WebSecurityConfigurationAdapter. Dans cette classe, vous allez injecter votre filtre 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());
    }
...
}

Vous n'avez pas besoin de mettre quoi que ce soit en rapport avec CORS dans votre contrôleur.

Frontend

Maintenant, dans le frontend, vous devez créer votre requête axios avec l'en-tête d'autorisation :

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

J'espère que cela vous aidera.

1 votes

Question de noob CORS, ceci n'est utilisé qu'en développement, n'est-ce pas ?

0 votes

Non, il est aussi et surtout en production.

12voto

Leonard Saers Points 146

La solution donnée par luschn et pillravi fonctionne bien sauf si vous recevez un Strict-Transport-Sécurité dans la réponse.

Ajout de withCredentials : true résoudra ce problème.

  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 votes

Qu'en est-il des données

4voto

Yuci Points 3538

Un exemple (axios_example.js) utilisant Axios dans 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);

Assurez-vous de le faire dans le répertoire de votre projet :

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

Vous pouvez ensuite tester l'API REST de Node.js à l'aide de votre navigateur : http://localhost:5000/search?queryStr=xxxxxxxxx

Réf : https://github.com/axios/axios

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X