Basisverificatie verzenden met axios

Ik probeer de volgende code te implementeren, maar iets werkt niet. Hier is de 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');
      });

Er wordt een 401-fout geretourneerd. Als ik het met Postman doe, is er een optie om Basic Auth in te stellen; als ik die velden niet invul, retourneert het ook 401, maar als ik dat doe, is het verzoek succesvol.

Enig idee wat ik verkeerd doe?

Hier is een deel van de documenten van de API over hoe dit te implementeren:

Deze service gebruikt basisverificatiegegevens in de koptekst om een ​​gebruikerssessie tot stand te brengen. Referenties worden gevalideerd tegen de Server. Als u deze webservice gebruikt, wordt een sessie gemaakt met de doorgegeven gebruikersreferenties en wordt een JSESSIONID geretourneerd. Deze JSESSIONID kan worden gebruikt in de volgende verzoeken om webservice-aanroepen te doen.*


Antwoord 1, autoriteit 100%

Er is een “auth”-parameter voor basisverificatie:

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

Bron/Documenten: https://github.com/mzabriskie/axios

Voorbeeld:

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

Antwoord 2, autoriteit 31%

De reden waarom de code in uw vraag niet authenticeert, is omdat u de auth in het data-object verzendt, niet in de configuratie, die het in de headers zal plaatsen. Volgens de axios docs, de alias aanvraagmethodevoor postis:

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

Om uw code te laten werken, moet u daarom een ​​leeg object voor gegevens verzenden:

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

Hetzelfde geldt voor het gebruik van de auth-parameter die wordt genoemd door @luschn. De volgende code is equivalent, maar gebruikt in plaats daarvan de parameter auth (en geeft ook een leeg gegevensobject door):

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

Antwoord 3, autoriteit 4%

Om de een of andere reden blokkeert dit simpele probleem veel ontwikkelaars. Ik worstelde vele uren met dit simpele ding. Dit probleem heeft zoveel dimensies:

  1. CORS (als je een frontend en backend gebruikt op verschillende domeinen en poorten.
  2. Backend CORS-configuratie
  3. Basisverificatieconfiguratie van Axios

CORS

Mijn setup voor ontwikkeling is met een vuejs webpack-applicatie die draait op localhost:8081 en een spring boot-applicatie die draait op localhost:8080. Dus wanneer ik de rest-API vanaf de frontend probeer aan te roepen, kan de browser me op geen enkele manier een reactie van de lente-backend laten ontvangen zonder de juiste CORS-instellingen. CORS kan worden gebruikt om de Cross Domain Script (XSS)-beveiliging die moderne browsers hebben, te versoepelen. Zoals ik dit begrijp, beschermen browsers uw SPA tegen een aanval door een XSS. Natuurlijk stelden sommige antwoorden op StackOverflow voor om een ​​Chrome-plug-in toe te voegen om XSS-beveiliging uit te schakelen, maar dit werkt echt EN als dat zo was, zou het onvermijdelijke probleem alleen maar voor later zijn.

Backend CORS-configuratie

Hier leest u hoe u CORS moet instellen in uw Spring Boot-app:

Voeg een CorsFilter-klasse toe om de juiste headers toe te voegen aan het antwoord op een clientverzoek. Access-Control-Allow-Origin en Access-Control-Allow-Headers zijn het belangrijkste om te hebben voor basisverificatie.

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

Voeg een configuratieklasse toe die Spring WebSecurityConfigurationAdapter uitbreidt. In deze les injecteer je je 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());
    }
...
}

Je hoeft niets met CORS in je controller te stoppen.

Frontend

Nu moet je in de frontend je axios-query maken met de Authorization-header:

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

Hopelijk helpt dit.


Antwoord 4, autoriteit 3%

De oplossing van luschn en pillravi werkt prima, tenzij je een Strict-Transport-Securityheader in het antwoord.

Het toevoegen van withCredentials: truelost dat probleem op.

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

Antwoord 5, autoriteit 2%

Hallo, u kunt dit op de volgende manier doen

   var username = '';
    var password = ''
    const token = `${username}:${password}`;
    const encodedToken = Buffer.from(token).toString('base64');
    const session_url = 'http://api_address/api/session_endpoint';
    var config = {
      method: 'get',
      url: session_url,
      headers: { 'Authorization': 'Basic '+ encodedToken }
    };
    axios(config)
    .then(function (response) {
      console.log(JSON.stringify(response.data));
    })
    .catch(function (error) {
      console.log(error);
    });

Antwoord 6, autoriteit 2%

Als u basisverificatie probeert uit te voeren, kunt u dit proberen:

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

Dit werkte voor mij. Ik hoop dat dat helpt


Antwoord 7

Een voorbeeld (axios_example.js) met 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);

Zorg ervoor dat u in uw projectdirectory het volgende doet:

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

U kunt vervolgens de Node.js REST API testen met uw browser op: http://localhost:5000/search?queryStr=xxxxxxxxx

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


Antwoord 8

Ik heb net dit probleem ondervonden, toen ik wat onderzoek deed, ontdekte ik dat de gegevenswaarden moeten worden verzonden als URLSearchParams, ik doe het als volgt:

getAuthToken: async () => {
const data = new URLSearchParams();
data.append('grant_type', 'client_credentials');
const fetchAuthToken = await axios({
  url: `${PAYMENT_URI}${PAYMENT_GET_TOKEN_PATH}`,
  method: 'POST',
  auth: {
    username: PAYMENT_CLIENT_ID,
    password: PAYMENT_SECRET,
  },
  headers: {
    Accept: 'application/json',
    'Accept-Language': 'en_US',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Access-Control-Allow-Origin': '*',
  },
  data,
  withCredentials: true,
});
return fetchAuthToken;

},


Antwoord 9

const auth = {
            username : 'test',
            password : 'test'
        }
const response =  await axios.get(yourUrl,{auth}) 

dit is werk als je basisverificatie gebruikt


Antwoord 10

Ik heb axios.interceptors.request.usegebruikt om basisverificatiegegevens te configureren. Ik heb een Backend Springboot-toepassing (met SpringSecurity) met een eenvoudig GET-eindpunt. De Frontend VueJs-app en Backend draaien op verschillende poorten.

axios.js

import axios from "axios";
const api = axios.create({
  baseURL: "http://api_address",
  timeout: 30000,
});
api.interceptors.request.use(
  async (config) => {
    const basicAuthCredentials = btoa("xxxx" + ":" + "xxxx");
    config.headers.common["Authorization"] = "Basic " + basicAuthCredentials;
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);
export default api;

backend.js

import axios from "@/services/axios";
const BackendAPI = {
  listUsers: async () => {
    return axios({
      url: '/users',
      method: 'GET',
      responseType: 'json',
    });
  },
};
export { BackendAPI };

Gevolgd door de VUE-component Users.vue

...
<script>
import { BackendAPI } from '@/services/backend';
export default {
  name: "Users",
  data() {
    return {
      usersList: [],
    }
  },
  methods: {
    async listUsers() {
      const response = await BackendAPI.listUsers();
      this.usersList = response.data;
    },
  },
};
</script>

De backend springt SecurityConfig.javauit met httpBasic als authenticatie en zowel cors als csrf uitgeschakeld.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/actuator/*")
        .permitAll()
        .anyRequest()
        .authenticated()
        .and()
        .httpBasic()
        .and()
        .cors()
        .disable()
        .csrf()
        .disable();
  }
}

Other episodes