Как отправить запрос с дайджест-аутентификацией в angular ionic. Я пробовал приведенный ниже код для запроса сервера, но он не принимает заголовок и не всплывает экран входа в систему. может ли кто-нибудь помочь мне найти правильный способ отправки дайджест-аутентификации с использованием ionic angular.

this.headers = new Headers();
        this.headers.append('Content-Type', 'text/plain\r\n');
        this.headers.append('Authorization', 'Digest Auth'
        + ('username=admin')
        + ('password=Admin')
        + ('realm=172fbc06f747cfecc88c461e')
        + ('nonce=94f6b93716')
        + ('qop=auth')
        + ('nc=0000008a')
        + ('default_device=default'));
        var requestOptions = {
            method: 'GET',
            headers: this.headers,
            redirect: 'follow'
          };

        return this.http.get('/command/analy/analyx.cgi?AppControl=' + data ,requestOptions)
            .map(response => {
                reslt = response.ok;
                console.log("RESLT" + reslt)
                return reslt;
            })

Прокси

{
    "name": "ionic4-angular7-crud",
    "app_id": "",
    "type": "ionic-angular",
    "proxies": [
                 {
                    "path": "/command",
                    "proxyUrl": "http://192.168.10.109/command/"
                 }
                 ],
                 "integrations": {
         "cordova": {}
      }
    }

Все еще в хроме, я получаю ошибку CORS. может ли кто-нибудь помочь мне решить эту проблему

Пытался отключить веб-безопасность Chrome, и сообщение об ошибке CROSS не отображается, но перенаправляется на HTTPS, даже если я напрямую вызываю http.

Chrome.exe --user-data-dir = "C: / Chrome dev session" --disable-web-security

1
ndh 29 Июл 2020 в 10:14
ERR_CONNECTION_REFUSED не имеет ничего общего с аутентификацией. Даже если вы удалите заголовок, вы получите ошибку ERR_CONNECTION_REFUSED. Можешь попробовать пропинговать IP-адрес и взять его оттуда? Кстати, «Access-Control-Allow-Origin» не является заголовком на стороне запроса, он должен жить на ресурсе, на который вы отправляете запрос. Если вы работаете с локального хоста и вам нужно делать запросы из разных источников, я предлагаю вместо этого запустить прокси.
 – 
Jiri Kralovec
29 Июл 2020 в 10:40
Я попытался настроить прокси, и он все равно блокируется. удалил заголовок из приведенного выше кода. есть ли какой-нибудь плагин для дайджест-аутентификации
 – 
ndh
29 Июл 2020 в 13:03
Ну если вы удалили шапку то авторизация не ваша проблема. Если бы это было так, вы бы получили ответ UNAUTHORIZED (при условии, что ресурс настроен правильно). Вы уже пробовали пинговать IP?
 – 
Jiri Kralovec
29 Июл 2020 в 16:52
Является ли дайджест-запрос, который я написал выше, правильным или нет. помогите мне, если это не способ сделать дайджест-аутентификацию
 – 
ndh
3 Авг 2020 в 08:07
Вы меня не слышите, ваша проблема, скорее всего, даже не связана с авторизацией (по крайней мере, ошибка об этом не говорит). Однако на самом деле это не так - кодирование имени пользователя и пароля в Base64 не является авторизацией Digest - stackoverflow.com/questions/9534602/….
 – 
Jiri Kralovec
3 Авг 2020 в 09:18

1 ответ

Лучший ответ

Я подумал о том, чтобы поделиться решением, которое я нашел для решения этой проблемы. на самом деле я пытался сделать это точно так же, как обычную аутентификацию, но дайджест-аутентификация похожа на двухэтапную аутентификацию. необходимо дважды позвонить, чтобы получить ответ. в исходном запросе сервер предоставит нам REALM, nonce и т. д., и с этим токеном нам нужно хешировать его с помощью MD5 (CryptoJS). Пожалуйста, найдите приведенный ниже код для дайджест-аутентификации.

// зависит от хеширования CryptoJS MD5: // https: // cdnjs. cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js

var digestAuthRequest = function (method, url, username, password) {
var self = this;

 if (typeof CryptoJS === 'undefined' && typeof require === 'function') {
    var CryptoJS = require('crypto-js');
 }

this.scheme = null; // we just echo the scheme, to allow for 'Digest', 'X-Digest', 'JDigest' etc
this.nonce = null; // server issued nonce
this.realm = null; // server issued realm
this.qop = null; // "quality of protection" - '' or 'auth' or 'auth-int'
this.response = null; // hashed response to server challenge
this.opaque = null; // hashed response to server challenge
this.nc = 1; // nonce count - increments with each request used with the same nonce
this.cnonce = null; // client nonce

// settings
this.timeout = 10000; // timeout
this.loggingOn = true; // toggle console logging

// determine if a post, so that request will send data
this.post = false;
if (method.toLowerCase() === 'post' || method.toLowerCase() === 'put') {
    this.post = true;
}

// start here
// successFn - will be passed JSON data
// errorFn - will be passed error status code
// data - optional, for POSTS
this.request = function (successFn, errorFn, data) {
    // posts data as JSON if there is any
    if (data) {
        self.data = JSON.stringify(data);
    }
    self.successFn = successFn;
    self.errorFn = errorFn;
    console.log('self.nonce' + self.nonce);
    if (!self.nonce) {
        self.makeUnauthenticatedRequest(self.data);
    } else {
        self.makeAuthenticatedRequest();
    }
}
this.makeUnauthenticatedRequest = function (data) {
    self.firstRequest = new XMLHttpRequest();
    self.firstRequest.open(method, url, true);
    self.firstRequest.timeout = self.timeout;
    // if we are posting, add appropriate headers
    if (self.post) {
        self.firstRequest.setRequestHeader('Content-type', 'application/json');
    }

    self.firstRequest.onreadystatechange = function () {
        console.log("self.firstRequest.readyState" + self.firstRequest.readyState);
        // 2: received headers,  3: loading, 4: done
        if (self.firstRequest.readyState === 2) {
            var responseHeaders = self.firstRequest.getAllResponseHeaders();

            ResponseHeader = responseHeaders.split('\n');
            //responseHeaders = responseHeaders.split('\n');
            // get authenticate header
            var digestHeaders;
            console.log('digestHeaders 0 ' + digestHeaders + ResponseHeader.length);
            for (var i = 0; i < ResponseHeader.length; i++) {
                if (ResponseHeader[i].match('www-authenticate') != null) {
                    digestHeaders = ResponseHeader[i];
                }
            }
            if (digestHeaders != null) {
                // parse auth header and get digest auth keys
                digestHeaders = digestHeaders.slice(digestHeaders.indexOf(':') + 1, -1);
                digestHeaders = digestHeaders.split(',');
                self.scheme = digestHeaders[0].split(/\s/)[1];
                for (var i = 0; i < digestHeaders.length; i++) {
                    var equalIndex = digestHeaders[i].indexOf('='),
                        key = digestHeaders[i].substring(0, equalIndex),
                        val = digestHeaders[i].substring(equalIndex + 1);
                    val = val.replace(/['"]+/g, '');
                    // find realm
                    if (key.match(/realm/i) != null) {
                        self.realm = val;
                    }
                    // find nonce
                    if (key.match(/nonce/i) != null) {
                        self.nonce = val;
                    }
                    // find opaque
                    if (key.match(/opaque/i) != null) {
                        self.opaque = val;
                    }
                    // find QOP
                    if (key.match(/qop/i) != null) {
                        self.qop = val;
                    }
                }
                // client generated keys
                self.cnonce = self.generateCnonce();
                self.nc++;
                // if logging, show headers received:
                self.log('received headers:');
                self.log('  realm: ' + self.realm);
                self.log('  nonce: ' + self.nonce);
                self.log('  opaque: ' + self.opaque);
                self.log('  qop: ' + self.qop);
                // now we can make an authenticated request
                self.makeAuthenticatedRequest();
            }
        }
        if (self.firstRequest.readyState === 4) {
            if (self.firstRequest.status === 200) {
                self.log('Authentication not required for ' + url);
                if (self.firstRequest.responseText !== 'undefined') {
                    if (self.firstRequest.responseText.length > 0) {
                        // If JSON, parse and return object
                        if (self.isJson(self.firstRequest.responseText)) {
                            self.successFn(JSON.parse(self.firstRequest.responseText));
                        } else {
                            self.successFn(self.firstRequest.responseText);
                        }
                    }
                } else {
                    self.successFn();
                }
            }
        }
    }
    // send
    if (self.post) {
        // in case digest auth not required
        self.firstRequest.send(self.data);
    } else {
        self.firstRequest.send();
    }
    self.log('Unauthenticated request to +++ ' + url);

    // handle error
    self.firstRequest.onerror = function () {
        if (self.firstRequest.status !== 401) {
            self.log('Error (' + self.firstRequest.status + ') on unauthenticated request to ' + url);
            self.errorFn(self.firstRequest.status);
        }
    }
}
this.makeAuthenticatedRequest = function () {
    self.response = self.formulateResponse();
    self.authenticatedRequest = new XMLHttpRequest();
    self.authenticatedRequest.open(method, url, true);
    self.authenticatedRequest.timeout = self.timeout;
    var digestAuthHeader = self.scheme + ' ' +
        'username="' + username + '", ' +
        'realm="' + self.realm + '", ' +
        'nonce="' + self.nonce + '", ' +
        'uri="' + url + '", ' +
        'response="' + self.response + '", ' +
        'opaque="' + self.opaque + '", ' +
        'qop=' + self.qop + ', ' +
        'nc=' + ('00000000' + self.nc).slice(-8) + ', ' +
        'cnonce="' + self.cnonce + '"';
    self.authenticatedRequest.setRequestHeader('Authorization', digestAuthHeader);
    self.log('digest auth header response to be sent:');
    self.log(digestAuthHeader);
    // if we are posting, add appropriate headers
    if (self.post) {
        self.authenticatedRequest.setRequestHeader('Content-type', 'application/json');
    }
    self.authenticatedRequest.onload = function () {
        // success
        if (self.authenticatedRequest.status >= 200 && self.authenticatedRequest.status < 400) {
            // increment nonce count
            self.nc++;
            // return data
            if (self.authenticatedRequest.responseText !== 'undefined' && self.authenticatedRequest.responseText.length > 0) {
                // If JSON, parse and return object
                if (self.isJson(self.authenticatedRequest.responseText)) {
                    self.successFn(JSON.parse(self.authenticatedRequest.responseText));
                } else {
                    self.successFn(self.authenticatedRequest.responseText);
                }
            } else {
                self.successFn();
            }
        }
        // failure
        else {
            self.nonce = null;
            self.errorFn(self.authenticatedRequest.status);
        }
    }
    // handle errors
    self.authenticatedRequest.onerror = function () {
        self.log('Error (' + self.authenticatedRequest.status + ') on authenticated request to ' + url);
        self.nonce = null;
        self.errorFn(self.authenticatedRequest.status);
    };
    // send
    if (self.post) {
        self.authenticatedRequest.send(self.data);
    } else {
        self.authenticatedRequest.send();
    }
    self.log('Authenticated request to ' + url);
}
// hash response based on server challenge
this.formulateResponse = function () {
    console.log('self.realm ' + self.realm);
    var HA1 = CryptoJS.MD5(username + ':' + self.realm + ':' + password).toString();
    var HA2 = CryptoJS.MD5(method + ':' + url).toString();
    var response = CryptoJS.MD5(HA1 + ':' +
        self.nonce + ':' +
        ('00000000' + self.nc).slice(-8) + ':' +
        self.cnonce + ':' +
        self.qop + ':' +
        HA2).toString();
    return response;
}
// generate 16 char client nonce
this.generateCnonce = function () {
    var characters = 'abcdef0123456789';
    var token = '';
    for (var i = 0; i < 16; i++) {
        var randNum = Math.round(Math.random() * characters.length);
        token += characters.substr(randNum, 1);
    }
    return token;
}
this.abort = function () {
    self.log('[digestAuthRequest] Aborted request to ' + url);
    if (self.firstRequest != null) {
        if (self.firstRequest.readyState != 4) self.firstRequest.abort();
    }
    if (self.authenticatedRequest != null) {
        if (self.authenticatedRequest.readyState != 4) self.authenticatedRequest.abort();
    }
}
this.isJson = function (str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}
this.log = function (str) {
    if (self.loggingOn) {
        console.log('[digestAuthRequest] ' + str);
    }
}
this.version = function () { return '0.8.0' }}
1
ndh 16 Авг 2020 в 14:20
Как использовать этот код?
 – 
saomi
2 Мар 2022 в 19:33