wake-up-neo.com

So senden Sie Basic Auth mit Axios

Ich versuche den folgenden Code zu implementieren, aber etwas funktioniert nicht. Hier ist der 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');
  });

Es wird ein 401-Fehler zurückgegeben. Wenn ich es mit Postman mache, gibt es eine Option zum Einstellen von Basic Auth. Wenn ich diese Felder nicht ausfülle, wird auch 401 zurückgegeben. Ist dies der Fall, ist die Anforderung erfolgreich.

Irgendwelche Ideen, was ich falsch mache?

Hier ist ein Teil der Dokumentation der API, wie Sie dies implementieren können:

Dieser Dienst verwendet Basisauthentifizierungsinformationen im Header, um eine Benutzersitzung einzurichten. Anmeldeinformationen werden gegen den Server geprüft. Mit diesem Webdienst wird eine Sitzung mit den übergebenen Benutzeranmeldeinformationen erstellt und eine JSESSIONID zurückgegeben. Diese JSESSIONID kann in den nachfolgenden Anforderungen für Webdienstaufrufe verwendet werden. *

34
Emmanuel

Es gibt einen "Auth" -Parameter für Basic Auth:

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

Quelle/Dokumente: https://github.com/mzabriskie/axios

46
luschn

Der Grund, warum sich der Code in Ihrer Frage nicht authentifiziert, liegt darin, dass Sie die Authentifizierung im Datenobjekt senden, nicht in der Konfiguration, die ihn in die Kopfzeilen setzt. Gemäß der axios docs lautet der Alias ​​[] der request-Methode für post:

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

Damit Ihr Code funktioniert, müssen Sie ein leeres Objekt für Daten senden:

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

Gleiches gilt für die Verwendung des von @luschn angegebenen auth-Parameters. Der folgende Code ist gleichwertig, verwendet jedoch stattdessen den Parameter auth (und übergibt auch ein leeres Datenobjekt):

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

Aus einigen Gründen blockiert dieses einfache Problem viele Entwickler. Ich hatte viele Stunden mit dieser einfachen Sache zu kämpfen. Dieses Problem so viele Dimensionen:

  1. CORS (wenn Sie ein Frontend und Backend für verschiedene Domänen und Ports verwenden).
  2. Backend CORS Konfiguration
  3. Grundlegende Authentifizierungskonfiguration von Axios

CORS

Mein Setup für die Entwicklung besteht aus einer vuejs-Webpack-Anwendung, die auf localhost: 8081 ausgeführt wird, und einer Spring-Boot-Anwendung, die auf localhost: 8080 ausgeführt wird. Wenn ich also versuche, die Rest-API vom Frontend aus aufzurufen, kann der Browser auf keinen Fall zulassen, dass ich vom Spring-Backend eine Antwort erhalte, ohne die richtigen CORS-Einstellungen vorzunehmen. CORS kann verwendet werden, um den XSS-Schutz (Cross Domain Script) moderner Browser zu lockern. Soweit ich weiß, schützen Browser Ihr SPA vor Angriffen durch ein XSS. Einige Antworten auf StackOverflow schlugen natürlich vor, ein chrome) - Plugin hinzuzufügen, um den XSS-Schutz zu deaktivieren, aber das funktioniert wirklich, UND wenn ja, würde es das unvermeidliche Problem nur für später verschieben.

Backend CORS Konfiguration

So sollten Sie CORS in Ihrer Spring Boot-App einrichten:

Fügen Sie eine CorsFilter-Klasse hinzu, um der Antwort auf eine Clientanforderung die richtigen Header hinzuzufügen. Access-Control-Allow-Origin und Access-Control-Allow-Header sind das Wichtigste für die Basisauthentifizierung.

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

    }
...
}

Fügen Sie eine Konfigurationsklasse hinzu, die Spring WebSecurityConfigurationAdapter erweitert. In dieser Klasse injizieren Sie Ihren CORS-Filter:

@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());
    }
...
}

Sie müssen nichts in Bezug auf CORS in Ihren Controller einfügen.

Frontend

Jetzt müssen Sie im Frontend Ihre Axios-Abfrage mit dem Authorization-Header erstellen:

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

Hoffe das hilft.

3
Erick Audet

Die Lösung von luschn und pillravi funktioniert einwandfrei, es sei denn, Sie erhalten in der Antwort den Header Strict-Transport-Security .

Durch Hinzufügen von withCredentials: true wird dieses Problem behoben.

  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
Leonard Saers

Ein Beispiel (axios_example.js), das Axios in Node.js verwendet:

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

Stellen Sie sicher, dass Sie in Ihrem Projektverzeichnis Folgendes tun:

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

Anschließend können Sie die Node.js REST - API mithilfe Ihres Browsers testen: http://localhost:5000/search?queryStr=xxxxxxxxx

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

0
Yuci