如何在 angular ionic 中使用 Digest 身份验证发送请求
How to send request with Digest authentication in angular ionic
如何在 angular ionic 中使用 Digest 身份验证发送请求。我已尝试使用以下代码请求服务器,但它不接受 header 并弹出登录屏幕。谁能帮我找到使用 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": {}
}
}
仍在 chrome 我收到 CROS 错误。谁能帮我解决这个问题
尝试禁用 chrome 网络安全,它没有显示 CROS 错误消息,但它正在转发到 HTTPS,即使我直接调用了 http。
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
我想分享我找到的解决这个问题的方法。实际上,我正在尝试完全像基本身份验证一样执行此操作,但摘要身份验证就像两步身份验证。需要拨打两次电话才能得到回应。在初始请求中,服务器将为我们提供 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' }}
如何在 angular ionic 中使用 Digest 身份验证发送请求。我已尝试使用以下代码请求服务器,但它不接受 header 并弹出登录屏幕。谁能帮我找到使用 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": {}
}
}
仍在 chrome 我收到 CROS 错误。谁能帮我解决这个问题
尝试禁用 chrome 网络安全,它没有显示 CROS 错误消息,但它正在转发到 HTTPS,即使我直接调用了 http。
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
我想分享我找到的解决这个问题的方法。实际上,我正在尝试完全像基本身份验证一样执行此操作,但摘要身份验证就像两步身份验证。需要拨打两次电话才能得到回应。在初始请求中,服务器将为我们提供 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' }}