我在woocommerce rest api中收到无效的签名错误。我也在使用ddo https://github.com/ddo/oauth-1.0a的oauth 1.0a脚本。我生成了两次api密钥。还删除了de oauth脚本中的版本参数,如woocommerce rest api文档中所请求的那样http://woothemes.github.io/woocommerce-rest-api-docs/
URL
test.dev/wc-api/v3/orders/line_items?oauth_consumer_key=ck_858f9cf8cda8085d5677b2b1d4c12d10897e9702&oauth_nonce=MyriSapnWSopIusSjjuqJ8PLi6RWr0L9&oauth_signature=VfgINTX1FWYu551%2FxlLfipFnDQ8%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1443481966
错误
{"errors":[{"code":"woocommerce_api_authentication_error","message":"Invalid Signature - provided signature does not match"}]}
JS
var oauth = OAuth({
consumer: {
public: 'ck_858f9cf8cda8085d5677b2b1d4c12d10897e9702',
secret: 'cs_7f429ec99905bb444e290bd4852a0c0da2545b21 '
},
signature_method: 'HMAC-SHA1'
});
var request_data = {
url: 'http://test.dev/wc-api/v3/orders/line_items',
method: 'GET',
}
$http({
url: request_data.url,
method: request_data.get,
params: oauth.authorize(request_data)
}).then(function successCallback(response) {
console.log(response);
}, function errorCallback(response) {
console.log(response);
});;
答案 0 :(得分:1)
我刚注意到您的$ http方法获得的值request_data.get
而不是request_data.method
。我敢肯定你正在俯瞰大声笑
答案 1 :(得分:0)
使用Abdul Ahmad提供的服务修复了它:httpService.js
angular.module('httpService', []).factory('httpService', httpService);
httpService.$inject = ['$http', '$q'];
function httpService($http, $q) {
var methods = {
httpGet : 'GET',
httpPost : 'POST',
httpPut : 'PUT',
httpDelete : 'DELETE'
};
function baseGet(url) {
return $http.get(url).then(
function (result) {
return result.data;
},
function (result) {
return $q.reject(result);
}
);
}
function httpWithParams(url, method, params, data) {
return $http({
url: url,
method: method,
params: params,
data: data,
dataType: "json",
headers: {
"Content-Type": "application/json"
}
}).then(
function (result) {
return result.data;
},
function (result) {
return $q.reject(result);
}
);
}
function handleError(error) {
console.log(error);
}
return {
baseGet: baseGet,
httpWithParams: httpWithParams,
handleError: handleError,
methods: methods
}
}
然后用这个:
var oauth = OAuth({
consumer: {
public: 'ck_000',
secret: 'cs_000'
},
signature_method: 'HMAC-SHA1'
});
function getMyData() {
var request_data = {
url: 'http://test.dev/wc-api/v3/products',
method: 'get',
}
return returnData = httpService.httpWithParams(request_data.url, request_data.method, oauth.authorize(request_data))
.then(function(data) {
return data;
}, function(data) {
httpService.handleError(data);
return data;
});
}
在oauth文件中做了一些修改:
if (typeof(module) !== 'undefined' && typeof(exports) !== 'undefined') {
module.exports = OAuth;
var CryptoJS = require("crypto-js");
}
/**
* Constructor
* @param {Object} opts consumer key and secret
*/
function OAuth(opts) {
if(!(this instanceof OAuth)) {
return new OAuth(opts);
}
if(!opts) {
opts = {};
}
if(!opts.consumer) {
throw new Error('consumer option is required');
}
this.consumer = opts.consumer;
this.signature_method = opts.signature_method || 'HMAC-SHA1';
this.nonce_length = opts.nonce_length || 32;
//this.version = opts.version || '1.0';
this.parameter_seperator = opts.parameter_seperator || ', ';
if(typeof opts.last_ampersand === 'undefined') {
this.last_ampersand = true;
} else {
this.last_ampersand = opts.last_ampersand;
}
switch (this.signature_method) {
case 'HMAC-SHA1':
this.hash = function(base_string, key) {
return CryptoJS.HmacSHA1(base_string, key).toString(CryptoJS.enc.Base64);
};
break;
case 'HMAC-SHA256':
this.hash = function(base_string, key) {
return CryptoJS.HmacSHA256(base_string, key).toString(CryptoJS.enc.Base64);
};
break;
case 'PLAINTEXT':
this.hash = function(base_string, key) {
return key;
};
break;
case 'RSA-SHA1':
throw new Error('oauth-1.0a does not support this signature method right now. Coming Soon...');
default:
throw new Error('The OAuth 1.0a protocol defines three signature methods: HMAC-SHA1, RSA-SHA1, and PLAINTEXT only');
}
}
/**
* OAuth request authorize
* @param {Object} request data
* {
* method,
* url,
* data
* }
* @param {Object} public and secret token
* @return {Object} OAuth Authorized data
*/
OAuth.prototype.authorize = function(request, token) {
var oauth_data = {
oauth_consumer_key: this.consumer.public,
oauth_timestamp: this.getTimeStamp(),
oauth_nonce: this.getNonce(),
oauth_signature_method: this.signature_method
//oauth_version: this.version
};
if(!token) {
token = {};
}
if(token.public) {
oauth_data.oauth_token = token.public;
}
if(!request.data) {
request.data = {};
}
oauth_data.oauth_signature = this.getSignature(request, token.secret, oauth_data);
return oauth_data;
};
/**
* Create a OAuth Signature
* @param {Object} request data
* @param {Object} token_secret public and secret token
* @param {Object} oauth_data OAuth data
* @return {String} Signature
*/
OAuth.prototype.getSignature = function(request, token_secret, oauth_data) {
return this.hash(this.getBaseString(request, oauth_data), this.getSigningKey(token_secret));
};
/**
* Base String = Method + Base Url + ParameterString
* @param {Object} request data
* @param {Object} OAuth data
* @return {String} Base String
*/
OAuth.prototype.getBaseString = function(request, oauth_data) {
return request.method.toUpperCase() + '&' + this.percentEncode(this.getBaseUrl(request.url)) + '&' + this.percentEncode(this.getParameterString(request, oauth_data));
};
/**
* Get data from url
* -> merge with oauth data
* -> percent encode key & value
* -> sort
*
* @param {Object} request data
* @param {Object} OAuth data
* @return {Object} Parameter string data
*/
OAuth.prototype.getParameterString = function(request, oauth_data) {
var base_string_data = this.sortObject(this.percentEncodeData(this.mergeObject(oauth_data, this.mergeObject(request.data, this.deParamUrl(request.url)))));
var data_str = '';
//base_string_data to string
for(var key in base_string_data) {
data_str += key + '=' + base_string_data[key] + '&';
}
//remove the last character
data_str = data_str.substr(0, data_str.length - 1);
return data_str;
};
/**
* Create a Signing Key
* @param {String} token_secret Secret Token
* @return {String} Signing Key
*/
OAuth.prototype.getSigningKey = function(token_secret) {
token_secret = token_secret || '';
if(!this.last_ampersand && !token_secret) {
return this.percentEncode(this.consumer.secret);
}
return this.percentEncode(this.consumer.secret) + '&' + this.percentEncode(token_secret);
};
/**
* Get base url
* @param {String} url
* @return {String}
*/
OAuth.prototype.getBaseUrl = function(url) {
return url.split('?')[0];
};
/**
* Get data from String
* @param {String} string
* @return {Object}
*/
OAuth.prototype.deParam = function(string) {
var arr = string.split('&');
var data = {};
for(var i = 0; i < arr.length; i++) {
var item = arr[i].split('=');
data[item[0]] = decodeURIComponent(item[1]);
}
return data;
};
/**
* Get data from url
* @param {String} url
* @return {Object}
*/
OAuth.prototype.deParamUrl = function(url) {
var tmp = url.split('?');
if (tmp.length === 1)
return {};
return this.deParam(tmp[1]);
};
/**
* Percent Encode
* @param {String} str
* @return {String} percent encoded string
*/
OAuth.prototype.percentEncode = function(str) {
return encodeURIComponent(str)
.replace(/\!/g, "%21")
.replace(/\*/g, "%2A")
.replace(/\'/g, "%27")
.replace(/\(/g, "%28")
.replace(/\)/g, "%29");
};
/**
* Percent Encode Object
* @param {Object} data
* @return {Object} percent encoded data
*/
OAuth.prototype.percentEncodeData = function(data) {
var result = {};
for(var key in data) {
result[this.percentEncode(key)] = this.percentEncode(data[key]);
}
return result;
};
/**
* Get OAuth data as Header
* @param {Object} oauth_data
* @return {String} Header data key - value
*/
OAuth.prototype.toHeader = function(oauth_data) {
oauth_data = this.sortObject(oauth_data);
var header_value = 'OAuth ';
for(var key in oauth_data) {
if (key.indexOf('oauth_') === -1)
continue;
header_value += this.percentEncode(key) + '="' + this.percentEncode(oauth_data[key]) + '"' + this.parameter_seperator;
}
return {
Authorization: header_value.substr(0, header_value.length - this.parameter_seperator.length) //cut the last chars
};
};
/**
* Create a random word characters string with input length
* @return {String} a random word characters string
*/
OAuth.prototype.getNonce = function() {
var word_characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
var result = '';
for(var i = 0; i < this.nonce_length; i++) {
result += word_characters[parseInt(Math.random() * word_characters.length, 10)];
}
return result;
};
/**
* Get Current Unix TimeStamp
* @return {Int} current unix timestamp
*/
OAuth.prototype.getTimeStamp = function() {
return parseInt(new Date().getTime()/1000, 10);
};
////////////////////// HELPER FUNCTIONS //////////////////////
/**
* Merge object
* @param {Object} obj1
* @param {Object} obj2
* @return {Object}
*/
OAuth.prototype.mergeObject = function(obj1, obj2) {
var merged_obj = obj1;
for(var key in obj2) {
merged_obj[key] = obj2[key];
}
return merged_obj;
};
/**
* Sort object by key
* @param {Object} data
* @return {Object} sorted object
*/
OAuth.prototype.sortObject = function(data) {
var keys = Object.keys(data);
var result = {};
keys.sort();
for(var i = 0; i < keys.length; i++) {
var key = keys[i];
result[key] = data[key];
}
return result;
};