Commit 2ae0d43a by 宋毅

tj

parent 52a0289a
......@@ -172,6 +172,79 @@ class tmqueryCtl extends CtlBase {
return system.getResult(null, "操作失败");
}
}
async getJdSign(pobj, qobj, req) {
try {
const { Signer, Context } = require('../jd-gateway-sdk');
let ctx = new Context('x3k0s704lfun-test.cn-north-1.jdcloud-api.net', '/market/order/api/submit', 'POST', null, 'empty');
ctx.regionId = 'cn-north-1'
ctx.headers.set('content-type', 'application/json');
let credentials = {
accessKeyId: 'C6D680733C19362B5DF478207D6A90A4', //替换自己的AK
secretAccessKey: 'EB9AFEE49CE41700CADD5F2EE3B2122C' //替换自己的SK--jd>>>>>>>
}
//测试报文:
//ctx.body = "pin=jcloud_pRiHQTd&serviceId=580010&itemCode=FW_GOODS-580010-1&platform=6"
//POST
var qs = require('querystring');
var post_data = { pin: "jcloud_pRiHQTd", serviceId: 580010, itemCode: "FW_GOODS-580010-1", platform: 6, orderNum: 1, articleType: 1 };//这是需要提交的数据
var tmpContent = JSON.stringify(post_data);
var tmpContentLength = Buffer.byteLength(tmpContent);
var content = qs.stringify(post_data);
ctx.body = tmpContent;
ctx.method = 'POST'
var signer = new Signer(ctx, credentials);
ctx.headers.set('Content-Length', tmpContentLength)
ctx.buildNonce()
var dd = new Date();
var auth = signer.sign(dd)
console.log("POST签名为:", auth)
ctx.headers.set('Authorization', auth)
////////////////////////////////////////////////////////////////////////////////////////////////////////////
var http = require('https');
var options = {
host: 'x3k0s704lfun-test.cn-north-1.jdcloud-api.net',
port: 443,
path: '/market/order/api/submit',
method: 'POST',
headers: {
}
};
for (let [key, value] of ctx.headers) {
options.headers[key] = value
}
console.log("\n post options:\n", options);
console.log("\n tmpContent:\n", tmpContent);
var req = http.request(options, function (res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
var _data = '';
res.on('data', function (chunk) {
_data += chunk;
});
res.on('end', function () {
console.log("\n--->>\nresult:", _data)
});
});
req.on('error', (e) => {
console.error(`请求遇到问题-------------: ${e.message}`);
});
req.write(tmpContent);
req.end();
} catch (errorMsg) {
console.log(errorMsg, "--jd>>>>>>>errorMsg..............................>>>>>>");
}
}
}
module.exports = tmqueryCtl;
......
module.exports={
Signer:require('./signer'),
Context:require('./requestContext')
}
\ No newline at end of file
const util = require('./util')
const uuid=require('uuid')
const NOUNCEHEADER='x-jdcloud-nonce'
class Context {
constructor(host,path,method,headers,serviceName='',regionId='')
{
if(!host)
throw new Error("host is required")
if(!path)
throw new Error("path is required")
if(!method)
throw new Error("method is required")
this.host=host
this.headers=headers||new Map()
this.method=method
this.path=util.uriEscapePath(path)
this.serviceName=serviceName
this.regionId=regionId
}
buildNonce()
{
this.headers.set(NOUNCEHEADER,uuid.v4())
}
setNonce(nonce)
{
this.headers.set(NOUNCEHEADER,nonce)
}
check()
{
if(!this.headers.get(NOUNCEHEADER))
throw new Error("header['x-jdcloud-nonce'] is required")
if(!this.regionId)
throw new Error("regionId is required")
}
buildQuery (queryParams) {
var queryParamsWithoutEmptyItem = {}
var keys = Object.keys(queryParams)
for (let key of keys) {
if (queryParams[key] !== undefined) {
queryParamsWithoutEmptyItem[key] = queryParams[key]
}
}
return util.queryParamsToString(queryParamsWithoutEmptyItem)
}
}
module.exports=Context
// Copyright 2018 JDCLOUD.COM
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License
// This signer is modified from AWS V4 signer algorithm.
var util = require('../util')
var v2Credentials = require('./v2_credentials')
module.exports = class SignerV2 {
constructor (request,credentials,logger=console.log) {
this.signatureCache = true
this.algorithm = 'JDCLOUD2-HMAC-SHA256'
this.unsignableHeaders = [
'authorization',
'user-agent',
'x-jdcloud-id',
'x-jcloud-id',
'x-jdcloud-content-sha256'
]
this.signableHeaders = [
'content-type',
'host',
'x-jdcloud-date',
'x-jdcloud-nonce'
]
this.request=request
this.headers=request.headers
this.serviceName =request.serviceName
this.logger=logger
this.credentials=credentials
// this.signatureCache = typeof options.signatureCache === 'boolean' ? options.signatureCache : true;
}
setSignableHeaders(signableHeaders)
{
let headers=['x-jdcloud-nonce']
if(this.headers.has('x-jdcloud-security-token'))
headers.push('x-jdcloud-security-token')
for(let header of signableHeaders)
{
headers.push(header)
}
this.signableHeaders=[...new Set(headers)]
}
addAuthorization (date) {
// var datetime = '20180119T070300Z';
this.request.check()
var datetime = util.date.iso8601(date).replace(/[:-]|\.\d{3}/g, '')
this.addHeaders(this.credentials, datetime)
if (!this.headers.get('x-jdcloud-oauth2-token')) {
this.headers.set(
'Authorization',
this.authorization(this.credentials, datetime)
)
}
}
sign(date)
{
this.request.check()
var datetime = util.date.iso8601(date).replace(/[:-]|\.\d{3}/g, '')
this.addHeaders(this.credentials, datetime)
return this.authorization(this.credentials, datetime)
}
addHeaders (credentials, datetime) {
this.headers.set('x-jdcloud-date', datetime)
this.headers.set(
'host',
this.request.host
)
}
signedHeaders () {
var keys = []
this.headers.forEach((value, key) => {
key = key.toLowerCase()
if (this.isSignableHeader(key)) {
keys.push(key)
}
})
return keys.sort().join(';')
}
credentialString (datetime) {
return v2Credentials.createScope(
datetime.substr(0, 8),
this.request.regionId,
this.serviceName
)
}
signature (credentials, datetime) {
var signingKey = v2Credentials.getSigningKey(
credentials,
datetime.substr(0, 8),
this.request.regionId,
this.serviceName,
this.signatureCache
)
return util.crypto.hmac(signingKey, this.stringToSign(datetime), 'hex')
}
stringToSign (datetime) {
var parts = []
parts.push(this.algorithm)
parts.push(datetime)
parts.push(this.credentialString(datetime))
parts.push(this.hexEncodedHash(this.canonicalString()))
this.logger('StringToSign is \n' + JSON.stringify(parts), 'DEBUG')
return parts.join('\n')
}
// 构建标准签名字符串
canonicalString () {
var parts = []
var pathname = this.request.path
parts.push(this.request.method)
parts.push(pathname)
parts.push(this.request.query)
parts.push(this.canonicalHeaders() + '\n')
parts.push(this.signedHeaders())
parts.push(this.hexEncodedBodyHash())
this.logger(
'canonicalString is \n' + JSON.stringify(parts),
'DEBUG'
)
return parts.join('\n')
}
canonicalHeaders () {
var headers = []
this.headers.forEach((value, key) => {
headers.push([key, value])
})
headers.sort(function (a, b) {
return a[0].toLowerCase() < b[0].toLowerCase() ? -1 : 1
})
var parts = []
util.arrayEach.call(this, headers, function (item) {
var key = item[0].toLowerCase()
if (this.isSignableHeader(key)) {
var value = item[1]
if (
typeof value === 'undefined' ||
value === null ||
typeof value.toString !== 'function'
) {
throw util.error(
new Error('Header ' + key + ' contains invalid value'),
{
code: 'InvalidHeader'
}
)
}
parts.push(key + ':' + this.canonicalHeaderValues(value.toString()))
}
})
return parts.join('\n')
}
canonicalHeaderValues (values) {
return values.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '')
}
authorization (credentials, datetime) {
var parts = []
var credString = this.credentialString(datetime)
parts.push(
this.algorithm +
' Credential=' +
credentials.accessKeyId +
'/' +
credString
)
parts.push('SignedHeaders=' + this.signedHeaders())
parts.push('Signature=' + this.signature(credentials, datetime))
this.logger('Signature is \n' + JSON.stringify(parts), 'DEBUG')
return parts.join(', ')
}
hexEncodedHash (string) {
return util.crypto.sha256(string, 'hex')
}
hexEncodedBodyHash () {
return (
this.headers.get('x-jdcloud-content-sha256') ||
this.hexEncodedHash(this.request.body || '')
)
/* var request = this.request;
if (this.isPresigned() && this.serviceName === 's3' && !request.body) {
return 'UNSIGNED-PAYLOAD';
} else if (request.headers['X-Amz-Content-Sha256']) {
return request.headers['X-Amz-Content-Sha256'];
} else {
return this.hexEncodedHash(this.request.body || '');
} */
}
isSignableHeader (key) {
return this.signableHeaders.includes(key.toLowerCase())
}
}
var cachedSecret = {}
var cacheQueue = []
var maxCacheEntries = 50
var v2Identifier = 'jdcloud2_request'
var util = require('../util')
module.exports = {
/**
* @api private
*
* @param date [String]
* @param region [String]
* @param serviceName [String]
* @return [String]
*/
createScope: function createScope (date, region, serviceName) {
return [date.substr(0, 8), region, serviceName, v2Identifier].join('/')
},
/**
* @api private
*
* @param credentials [Credentials]
* @param date [String]
* @param region [String]
* @param service [String]
* @param shouldCache [Boolean]
* @return [String]
*/
getSigningKey: function getSigningKey (
credentials,
date,
region,
service,
shouldCache
) {
var credsIdentifier = util.crypto.hmac(
credentials.secretAccessKey,
credentials.accessKeyId,
'base64'
)
var cacheKey = [credsIdentifier, date, region, service].join('_')
shouldCache = shouldCache !== false
if (shouldCache && cacheKey in cachedSecret) {
return cachedSecret[cacheKey]
}
var kDate = util.crypto.hmac(
'JDCLOUD2' + credentials.secretAccessKey,
date,
'buffer'
)
var kRegion = util.crypto.hmac(kDate, region, 'buffer')
var kService = util.crypto.hmac(kRegion, service, 'buffer')
var signingKey = util.crypto.hmac(kService, v2Identifier, 'buffer')
if (shouldCache) {
cachedSecret[cacheKey] = signingKey
cacheQueue.push(cacheKey)
if (cacheQueue.length > maxCacheEntries) {
// remove the oldest entry (not the least recently used)
delete cachedSecret[cacheQueue.shift()]
}
}
return signingKey
},
/**
* @api private
*
* Empties the derived signing key cache. Made available for testing purposes
* only.
*/
emptyCache: function emptyCache () {
cachedSecret = {}
cacheQueue = []
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment