国家防沉迷实名认证系统--NODEJS

【国家防沉迷实名认证系统–NODEJS】

首先是插件引入和常量定义

const https = require('https');
const querystring = require("querystring");
const crypto = require('crypto');

let host = 'api.wlc.nppa.gov.cn';
let host2 = 'api2.wlc.nppa.gov.cn';
let path = '/idcard/authentication/check';
let queryPath = "/idcard/authentication/query";
let loginoutPath = "/behavior/collection/loginout";
let method = 'POST';
let secretKey = '';// TODO: 填写自己申请的认证数据
let appId = '';    // TODO: 填写自己申请的认证数据
let bizId = '';	   // TODO: 填写自己申请的认证数据
let signPreStr = secretKey + 'appId' + appId + 'bizId' + bizId + 'timestamps';

然后上代码:

/**
 * 请求身份认证
 * @param {String}   ai  可使用用户账号id
 * @param {String}   identity  身份证号
 * @param {String}   name  真实名字
 * @param {Function} cb  回调
 */
Authentication.prototype.getIdentityResult = function (ai, identity, name, cb) {
    let idJson = {
        'ai': ai,
        'name': name,
        'idNum': identity
    };
    let postData = JSON.stringify(idJson);

    let encr = encrypt(postData);
    let encrData = JSON.stringify({
        'data': encr
    });
    let timestamps = Date.now();
    let signStr = signPreStr + timestamps + encrData;
    let sha256 = crypto.createHash('sha256');
    sha256.update(signStr, 'utf8');
    let sign = sha256.digest('hex');

    let identityResult = '';
    let options = {
        hostname: host,
        path: path,
        method: method,
        headers: {
            'Content-Type': 'application/json; charset=utf-8',
            'Content-Length': encrData.length,
            'appId': appId,
            'bizId': bizId,
            'timestamps': timestamps,
            'sign': sign
        }
    };

    let self = this;
    let req = https.request(options, (res) => {
        res.setEncoding('utf-8');
        if (res.statusCode === 200) {
            res.on('data', (chunk) => {
                identityResult += chunk;
            });
            res.on('end', () => {
                logger.info('get identity result : %j, idJson: %j', identityResult, idJson);
                let result = JSON.parse(identityResult);
                if (0 === result.errcode) {
                    if (0 === result.data.result.status) {
                        // TODO: 认证成功回调
                        cb && cb(null, idJson);
                        return;
                    } else if (1 === result.data.result.status) {
                        // TODO: 认证超时回调
                        cb();
                        return;
                    }
                } else if (2004 === result.errcode) {
                    // TODO: 认证超时回调
                    cb();
                    return;
                }
                // TODO: 认证失败回调
                cb();
            });
        } else {
            // TODO: 网页请求失败回调
            cb();
        }
    });
    // 将数据写入请求主体。
    req.write(encrData);
    req.on('error', (e) => {
        // TODO: 网页请求出错回调
        cb();
    });
    req.end();
};

let encrypt = function (postData) {
    try {
        let key = Buffer.from(secretKey, 'hex');
        let iv = crypto.randomBytes(12);
        let cipher = crypto.createCipheriv('aes-128-gcm', key, iv);

        let encr = cipher.update(postData, 'utf8', 'base64');
        encr += cipher.final('base64');

        //cipher.getAuthTag() 方法返回一个 Buffer,它包含已从给定数据计算后的认证标签。
        //cipher.getAuthTag() 方法只能在使用 cipher.final() 之后调用 这里返回的是一个十六进制后的数组
        let tags = cipher.getAuthTag();
        encr = Buffer.from(encr, 'base64');

        //由于和java对应的AES/GCM/PKCS5Padding模式对应 所以采用这个拼接
        let totalLength = iv.length + encr.length + tags.length;
        let bufferData = Buffer.concat([iv, encr, tags], totalLength);

        return bufferData.toString('base64');
    } catch (e) {
        console.log("Encrypt is error", e);
        return null;
    }
};
/**
 * 查询认证信息
 * @param {String}   ai  可使用用户账号id
 * @param {Function} cb  回调
 */
Authentication.prototype.queryAuthentication = function (ai, cb) {
    let getData = querystring.stringify({
        'ai': ai
    });

    let timestamps = Date.now();
    let signStr = secretKey + 'ai' + ai + 'appId' + appId + 'bizId' + bizId + 'timestamps' + timestamps;
    let sha256 = crypto.createHash('sha256');
    sha256.update(signStr, 'utf8');
    let sign = sha256.digest('hex');

    let queryResult = '';
    let options = {
        hostname: host,
        path: queryPath + '?' + getData,
        method: 'GET',
        headers: {
            'appId': appId,
            'bizId': bizId,
            'timestamps': timestamps,
            'sign': sign
        }
    };

    let req = https.request(options, (res) => {
        res.setEncoding('utf-8');
        if (res.statusCode === 200) {
            res.on('data', (chunk) => {
                queryResult += chunk;
            });
            res.on('end', () => {
                logger.info('get identity result : %j, getData: %j', queryResult, getData);
                let result = JSON.parse(queryResult);
                if (0 === result.errcode) {
                    if (0 === result.data.result.status) {
                        // TODO: 认证成功回调
                        cb();
                        return;
                    } else if (1 === result.data.result.status) {
                        // TODO: 认证超时回调
                        cb();
                        return;
                    }
                } else if (2004 === result.errcode) {
                    // TODO: 认证超时回调
                    cb();
                    return;
                }

                // TODO: 认证失败回调
                cb();
            });
        } else {
            // TODO: 网页请求失败回调
            cb();
        }
    });
    req.on('error', (e) => {
        // TODO: 网页请求出错回调
        cb();
    });
    req.end();
};
/**
 * 注册限制   ct  用户行为数据上报类型0:已认证通过用户2:游客用户 di  游客模式设备标识,由游戏运营单位生成,游客用户下必填
 * @param {String}   si  游戏内部会话标识
 * @param {Number}   bt  游戏用户行为类型0:下线, 1:上线
 * @param {Number}   state
 * @param {String}   pi  已通过实名认证用户的唯一标识,已认证通过用户必填
 * @param {Function} cb  回调
 */
Authentication.prototype.loginout = function (si, bt, state, pi, cb) {
    let idJson = {
        "no": 1,
        "si": si,
        "bt": bt,
        "ot": Math.floor(Date.now() / 1000)
    };
    if (state === 1) {
        idJson.ct = 2; // 游客用户
        idJson.di = pi;
    } else {
        idJson.ct = 0; // 已认证用户
        idJson.pi = pi;
    }

    let postData = JSON.stringify({"collections": [idJson]});

    let encr = encrypt(postData);
    let encrData = JSON.stringify({
        'data': encr
    });
    let timestamps = Date.now();
    let signStr = signPreStr + timestamps + encrData;
    let sha256 = crypto.createHash('sha256');
    sha256.update(signStr, 'utf8');
    let sign = sha256.digest('hex');

    let identityResult = '';
    let options = {
        hostname: host2,
        path: loginoutPath,
        method: method,
        headers: {
            'Content-Type': 'application/json; charset=utf-8',
            'Content-Length': encrData.length,
            'appId': appId,
            'bizId': bizId,
            'timestamps': timestamps,
            'sign': sign
        }
    };

    let req = http.request(options, (res) => {
        res.setEncoding('utf-8');
        if (res.statusCode === 200) {
            res.on('data', (chunk) => {
                identityResult += chunk;
            });
            res.on('end', () => {
                logger.info('idJson: %j, loginout result : %j', idJson, identityResult);
                let result = JSON.parse(identityResult);
                if (0 === result.errcode) {
                    cb && cb(null, 200);
                    return;
                }

                cb && cb("error", 500);
            });
        } else {
            logger.error('Authentication loginout err code : %j, idJson: %j', res.statusCode, idJson);
            cb && cb("error", 500);
        }
    });
    // 将数据写入请求主体。
    req.write(encrData);
    req.on('error', (e) => {
        logger.error('Authentication loginout 请求遇到问题: %j, idJson: %j', e.message, idJson);
        cb && cb("error", 500);
    });
    req.end();
};
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泉o泉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值