美文网首页
nodejs soap

nodejs soap

作者: 无我_a50f | 来源:发表于2020-06-13 17:04 被阅读0次
  1. 使用 soapUI 获取 xml 传输配置
  2. 使用 request 封装 xml
const urlencode = require("urlencode");
const Parser = require("fast-xml-parser").j2xParser;
const parser = require("fast-xml-parser");
const request = require('request');
const crypto = require('crypto');
const fs = require('fs');
const _ = require('lodash');

module.exports = class extends think.Service{
    constructor(){
        super();
        this.fileSignModelIns = think.model('fileSign', {}, think.config('custom.appModules.web'));
        this.option = {
            url: think.config('custom.certsercureService'),
            method: 'POST',
            body: '',
            headers: {
                'Content-Type':'text/xml;charset=utf-8',
                'Accept-Encoding': 'gzip,deflate',
                'Content-Length':0,
                'SOAPAction':"",
                'Connection':"Keep-Alive"
            }
        };
    }

    /**
     * 生成签名
     * @params Object 参数需要签名的body
     */
    async createEncryption(params) {
        let xmlString = this.getXmlString(params, '方法2');
        let options = this.getOption(xmlString);
        let body = await this.httprequest(options);
        let body_ = parser.parse(body);
        let return_ = body_['soap:Envelope']['soap:Body']['ns2:xxxxxx'];
        return return_.return;
    }

    /**
     * 验证签名
     * @params Object 参数需要签名的body
     */
    async verifyEncryption(params, arg3) {
        let xmlString = this.getXmlString(params, '方法1', arg3);
        let options = this.getOption(xmlString);
        let body = await this.httprequest(options);
        let body_ = parser.parse(body);
        let return_ = body_['soap:Envelope']['soap:Body']['ns2:xxxxx'];
        return return_.return;
    }

    /**
     * 异步请求
     * @param options
     * @returns {Promise<*|Promise<unknown>>}
     */
    async httprequest(options){
        return new Promise((resolve, reject)=>{
            request(options, function(error, response, body) {
                if (!error && response.statusCode == 200) {
                    resolve(body)
                }
            });
        })
    }

    /**
     * 获取option
     * @xmlString xml字符串
     */
    getOption(xmlString){
        let headers = Object.assign({}, this.option.headers);
        headers['Content-Length'] = xmlString.length;
        let options = Object.assign({}, this.option);
        return Object.assign(options, {body: xmlString, headers} );
    }

    /**
     * @params json 参数需要签名的body
     * @type string 签名操作类型(生成,确认,更新,销毁)
     */
    getXmlString(params, type, arg3 = ''){
        let json = {
            "root":{
                "body": Object.assign({"systemId": "xxxxx"}, params)
            }
        };

        let xml = urlencode(new Parser().parse(json), 'utf-8');

        if(arg3 != ''){
            return `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:guot="http://xxxxxx.com/">
               <soapenv:Header/>
               <soapenv:Body>
                  <guot:${type}>
                     <!--Optional:-->
                     <arg0>xxxx</arg0>
                     <!--Optional:-->
                     <arg1>${arg3}</arg1>
                     <arg2>${xml}</arg2>
                  </guot:${type}>
               </soapenv:Body>
            </soapenv:Envelope>`;
        }

        return `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:guot="http://xxxxxx.com/">
               <soapenv:Header/>
               <soapenv:Body>
                  <guot:${type}>
                     <!--Optional:-->
                     <arg0>xxxx</arg0>
                     <!--Optional:-->
                     <arg1>${xml}</arg1>
                  </guot:${type}>
               </soapenv:Body>
            </soapenv:Envelope>`;
    }

    /**
     * 给文件签名
     * @param path
     * @returns {Promise<*>}
     */
    async createFileEncryption(path){
        let hash = this.createFileHash256Sync(path);
        let params = {
            hash,
            path
        };
        let signId = await this.createEncryption(params);
        await this.fileSignModelIns.where({path}).delete();
        let result = await this.fileSignModelIns.add({signId, path});

        return signId;
    }

    /**
     * 批量给文件签名
     * @param pathArr
     * @returns {Promise<*>}
     */
    async batchCreateFileEncryption(pathArr){
        let arr = pathArr.map(async (path) => {
            let hash = this.createFileHash256Sync(path);
            let params = {
                hash,
                path
            };
            let signId = await this.createEncryption(params);
            return {signId, path}
        });
        Promise.all(arr).then(async result=>{
            await this.fileSignModelIns.where({path: ['IN', pathArr]}).delete();
            await this.fileSignModelIns.addMany(result);
        });
    }

    /**
     * 批量验证文件签名
     * @param pathArr
     * @returns {Promise<*>}
     */
    async batchVerifyFileEncryption(pathArr){
        let result = await this.fileSignModelIns.where({path: ['IN', pathArr]}).select();
        let promiseArr = result.map(async (item) => {
            let hash = this.createFileHash256Sync(item.path);
            let params = {
                hash,
                path: item.path
            };
            return await this.verifyEncryption(params, item.signId);
        });

        let flags = await Promise.all(promiseArr);
        let idx = flags.indexOf(false);

        if(idx > -1){
            return new Error(`文件 ${pathArr[idx]} 签名确认失败`)
        }else{
            return true;
        }
    }

    /**
     * 确认文件签名
     * @param path
     * @returns {Promise<*>}
     */
    async verifyFileEncryption(path){
        let hash = this.createFileHash256Sync(path);
        let params = {
            hash,
            path
        };

        let signObj = await this.fileSignModelIns.where({path}).find();
        if(signObj.signId != ''){
            return await this.verifyEncryption(params, signObj.signId);
        }else{
            return new Error("文件签名确认失败")
        }
    }

    /**
     * 创建文件hash
     * @param path
     * @returns {string}
     */
    createFileHash256Sync(path) {
        const buffer = fs.readFileSync(path);
        const fsHash = crypto.createHash('sha256');
        fsHash.update(buffer);
        const md5 = fsHash.digest('hex');
        return md5
     }
}

相关文章

网友评论

      本文标题:nodejs soap

      本文链接:https://www.haomeiwen.com/subject/bxhztktx.html