Cách gửi Auth cơ bản với axios


107

Tôi đang cố gắng triển khai mã sau, nhưng có điều gì đó không hoạt động. Đây là mã:

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

Nó trả về lỗi 401. Khi tôi làm điều đó với Postman, có một tùy chọn để đặt Basic Auth; nếu tôi không điền vào các trường đó, nó cũng trả về 401, nhưng nếu tôi điền, yêu cầu thành công.

Bất kỳ ý tưởng những gì tôi đang làm sai?

Dưới đây là một phần tài liệu của API về cách triển khai điều này:

Dịch vụ này sử dụng thông tin Xác thực Cơ bản trong tiêu đề để thiết lập phiên người dùng. Thông tin xác thực được xác thực dựa trên Máy chủ. Sử dụng dịch vụ web này sẽ tạo một phiên với thông tin đăng nhập người dùng được chuyển và trả về JSESSIONID. JSESSIONID này có thể được sử dụng trong các yêu cầu tiếp theo để thực hiện các cuộc gọi dịch vụ web. *

Câu trả lời:


152

Có một thông số "auth" cho Basic Auth:

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

Nguồn / Docs: https://github.com/mzabriskie/axios

Thí dụ:

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

4
xin chào, làm cách nào để đặt điều đó thành tất cả các cuộc gọi axios? Tôi cần thêm Xác thực cơ bản cho tất cả các lệnh gọi ajax. axios.defaults.auth = {username: 'dd', password: '##'} cái này không hiệu quả với tôi.
hkg328

có thể điều này sẽ hữu ích: gist.github.com/EQuimper/dc5fe02dcaca4469091729e1313f78d1
luschn

btw, bạn als có thể viết một wrapper xung quanh Axios cho những loại vật
luschn

Tôi đã thực hiện trình bao bọc cho điều đó. nhưng api đó cho tôi lỗi 401
hkg328

1
@ hkg328 bạn cần mã hóa chuỗi tên người dùng: mật khẩu thành base64 nếu bạn muốn đặt tiêu đề theo cách thủ công. một cái gì đó như nhập btoa từ 'btoa-lite'; token = btoa (tên người dùng + ':' + mật khẩu); sau đó đặt tiêu đề thành 'Cơ bản' + mã thông báo;
shrumm 19/03/18

54

Lý do mã trong câu hỏi của bạn không xác thực là vì bạn đang gửi auth trong đối tượng dữ liệu, không phải trong cấu hình, sẽ đặt nó trong tiêu đề. Theo tài liệu axios , bí danh phương thức yêu cầu cho postlà:

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

Do đó, để mã của bạn hoạt động, bạn cần gửi một đối tượng trống cho dữ liệu:

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

Điều này cũng đúng khi sử dụng tham số auth được @luschn đề cập. Đoạn mã sau là tương đương, nhưng thay vào đó sử dụng tham số auth (và cũng chuyển một đối tượng dữ liệu trống):

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
ĐIỀU NÀY
GIÚP ĐỠ, CẢM

1
Đây phải là câu trả lời được chấp nhận. Câu trả lời được chấp nhận chỉ là bản sao của tài liệu.
Sinister Beard,

5

Vì một số lý do, vấn đề đơn giản này đang chặn nhiều nhà phát triển. Tôi đã vật lộn nhiều giờ với điều đơn giản này. Vấn đề này theo nhiều chiều:

  1. CORS (nếu bạn đang sử dụng giao diện người dùng và phụ trợ trên các tên miền và cổng khác nhau.
  2. Cấu hình Backend CORS
  3. Cấu hình xác thực cơ bản của Axios

CORS

Thiết lập để phát triển của tôi là với một ứng dụng webpack vuejs chạy trên localhost: 8081 và một ứng dụng khởi động mùa xuân chạy trên localhost: 8080. Vì vậy, khi cố gắng gọi API nghỉ ngơi từ giao diện người dùng, không có cách nào mà trình duyệt cho phép tôi nhận được phản hồi từ chương trình phụ trợ mùa xuân mà không có cài đặt CORS thích hợp. CORS có thể được sử dụng để nới lỏng bảo vệ Tập lệnh tên miền chéo (XSS) mà các trình duyệt hiện đại có. Theo tôi hiểu điều này, các trình duyệt đang bảo vệ SPA của bạn khỏi bị tấn công bởi XSS. Tất nhiên, một số câu trả lời trên StackOverflow đề xuất thêm một plugin chrome để tắt tính năng bảo vệ XSS nhưng điều này thực sự hoạt động VÀ nếu có, sẽ chỉ đẩy vấn đề không thể tránh khỏi về sau.

Cấu hình CORS phụ trợ

Đây là cách bạn nên thiết lập CORS trong ứng dụng khởi động mùa xuân của mình:

Thêm một lớp CorsFilter để thêm các tiêu đề thích hợp trong phản hồi cho một yêu cầu của khách hàng. Access-Control-Allow-Origin và Access-Control-Allow-Headers là điều quan trọng nhất cần có để xác thực cơ bản.

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

    }
...
}

Thêm một lớp cấu hình mở rộng Spring WebSecurityConfigurationAdapter. Trong lớp này, bạn sẽ chèn bộ lọc CORS của mình:

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

Bạn không phải đặt bất cứ thứ gì liên quan đến CORS trong bộ điều khiển của mình.

Giao diện người dùng

Bây giờ, trong giao diện người dùng, bạn cần tạo truy vấn axios của mình với tiêu đề Ủy quyền:

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

Hi vọng điêu nay co ich.


câu hỏi của noob CORS, điều này chỉ được sử dụng trong phát triển, phải không?
Len Joseph

Không, nó cũng đang được sản xuất.
Erick Audet

3

Một ví dụ (axios_example.js) sử dụng Axios trong 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);

Hãy chắc chắn rằng trong thư mục dự án của bạn có:

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

Sau đó, bạn có thể kiểm tra API REST Node.js bằng trình duyệt của mình tại: http://localhost:5000/search?queryStr=xxxxxxxxx

Tham khảo: https://github.com/axios/axios


3

Giải pháp do luschn và tabletravi đưa ra hoạt động tốt trừ khi bạn nhận được tiêu đề Nghiêm ngặt-Vận chuyển-Bảo mật trong phản hồi.

Thêm withCredentials: true sẽ giải quyết vấn đề đó.

  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');
  });
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.