45 votes

Comment envoyer Basic Auth avec axios

Je suis en train 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');
  });

Elle retourne une erreur 401. Quand je le fais avec Facteur, il y a une option pour définir l'Authentification Basique; si je ne remplissez pas ces champs, il renvoie également 401, mais si je le fais, la demande est acceptée.

Les idées de ce que je fais mal?

Voici une partie de la documentation de l'API de la façon de mettre en œuvre ce:

Ce service utilise l'Authentification de Base de l'information dans l'en-tête pour établir une session utilisateur. Les informations d'identification sont validées sur le Serveur. L'utilisation de ce service web va créer une session avec l'utilisateur, les informations d'identification transmis et retourner un JSESSIONID. Cette JSESSIONID peut être utilisé dans la suite de la demande pour le web-les appels de service.*

61voto

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

26voto

pillravi Points 2413

La raison pour laquelle le code dans votre question n'est pas l'authentification est parce que vous êtes l'envoi de la auth dans l'objet de données, pas dans la config qui va le mettre dans les en-têtes. Par l' axios docs, la demande de la méthode d'alias pour post est:

axios.post(url[, données [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');
});

La même chose est vraie pour l'utilisation de l'authentification paramètre mentionné par @luschn. Le code suivant est équivalent, mais utilise le paramètre auth à la place (et aussi passe un vide d'objet de données):

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

1voto

Erick Audet Points 75

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

  1. De la SCRO (si vous utilisez un frontend et backend sur les différents domaines et les ports.
  2. Backend de la SCRO de Configuration
  3. L'Authentification de base de la configuration de l'Axios

De la SCRO

Ma configuration pour le développement est avec un vuejs webpack application en cours d'exécution sur localhost:8081 et un ressort de démarrage de l'application en cours d'exécution sur localhost:8080. Ainsi, lorsque vous essayez d'appeler l'API rest de l'interface, il n'y a aucun moyen que le navigateur me permettra de recevoir une réponse du printemps backend sans SCRO paramètres. La SCRO peut être utilisé pour détendre la Croix Domaine de Script (XSS) protection que les navigateurs modernes. Comme je le comprends, les navigateurs sont la protection de votre SPA à partir de cours d'une attaque XSS. Bien sûr, quelques réponses sur StackOverflow a suggéré d'ajouter un plugin chrome pour désactiver la protection XSS, mais cela fonctionne vraiment ET si elle l'était, ne serait que repousser l'inévitable problème pour plus tard.

Backend de la SCRO de configuration

Voici comment vous devriez le programme d'installation de la SCRO dans votre ressort de démarrage de l'app:

Ajouter un CorsFilter classe pour ajouter bon les en-têtes de la réponse à la requête d'un client. Access-Control-Allow-Origin et Access-Control-Allow-les en-Têtes sont la chose la plus importante à 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 s'étend du Printemps WebSecurityConfigurationAdapter. Dans cette classe, vous allez injecter des CORS du filtre:

@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 à mettre tout ce qui est lié à la SCRO dans votre contrôleur.

Frontend

Maintenant, dans le frontend vous avez besoin pour créer votre axios requête 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>

Espérons que cette aide.

0voto

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 que dans votre répertoire de projet vous faites:

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

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

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

0voto

Leonard Saers Points 146

La solution donnée par luschn et pillravi fonctionne bien à moins que vous ne receviez un en - tête Strict-Transport-Security dans la réponse.

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

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: