【nodejs】网易云信短信接入&融云IM-token获取

网易云信短信接口签名生成方法

短信接入文档

1.配置

在网易云信管理中心->应用管理->自己的应用里查看appkey和appsecret

【nodejs】网易云信短信接入&融云IM-token获取_第1张图片
Paste_Image.png
'sms':{
        appSecret:"xxxxxxxxxxxxx",
        appKey:"xxxxxxxxxxxxxx"
    }

2.生成签名

需要三样东西来生成签名

  • 密钥 appSecret
  • 随机字符串 nonce
  • 时间戳 CurTime
//生成随机字符串 借用微信的
const createNonceStr = function () {
    return Math.random().toString(36).substr(2, 15);
};
// 生成时间戳 秒值 借用微信的
const createTimestamp = function () {
    return parseInt(new Date().getTime() / 1000) + "";
};
//进行SHA1哈希计算,转化成16进制字符 这里用的库为jshashes
const generateSHA1SignatureByHex = (appSecret, nonce, timestamp) => {
    const sha1Str = appSecret + nonce + timestamp;
    const SHA1 = new Hashes.SHA1().hex(sha1Str)
    return SHA1;
}

可以不局限于这些生成方法 只要是满足位数条件都可以 比如生成随机字符串 可以用chance库也很不错,SHA1也有不少库digitalbazaar/forge、h2non/jshashes

3.拼请求参数

//可以写个业务方法包裹一下 或者直接在拼装header的方法散写也可以
const generateSignatureForCode = () => {
    const appSecret = Config.sms.appSecret;
    const Nonce = createNonceStr();
    const CurTime = createTimestamp();
    const SHA1 = Util.generateSHA1SignatureByHex(appSecret,Nonce,CurTime)
    return {
        Nonce:Nonce,
        CurTime:CurTime,
        SHA1:SHA1
    };
}
// 拼装请求头
const getRequestSmsHeaders = function () {

    const appkey = Config.sms.appKey;
    const SHA1 = Util.generateSignatureForCode({
        appsecret: Config.sms.appSecret,
    })
    return {
        'Content-Type': "application/x-www-form-urlencoded;charset=utf-8",
        'AppKey': appKey, //开发者平台分配的appkey 别写错了
        'Nonce': Nonce,
        'CurTime': CurTime,
        'CheckSum': SHA1
    }
}

4.发送请求

// 这里使用的request库 当然其他的随意
const requestService = function (options) {
    return new Promise(function (resolve, reject) {
        request(options, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                var info = JSON.parse(body);
                resolve(info)
            } else {
                reject(error);
            }
        });
    })
}

//返回值
出错情况最多的:
{ code: 414, msg: 'checksum' } 
文档里解释这是签名参数出错 但不是签名算法的问题 检查一下appKey appSecret的属性拼写
成功:
{ code: 200, msg: '1410', obj: '2846' }
obj为验证码
【nodejs】网易云信短信接入&融云IM-token获取_第2张图片
Paste_Image.png

融云IM-TOKEN方法

如法炮制,把请求头改成符合他条件的就好
文档 融云文档真是比网易的强太多

const getRequestHeaders = function () {

    const appkey = Config.im.appKey;
    const appSecret = Config.im.appSecret;
    const Nonce = Util.createNonceStr();
    const Timestamp = Util.createTimestamp();
    const SHA1HEX = Util.generateSHA1SignatureByHex(appSecret, Nonce, Timestamp);
    return {
        'Content-Type': "application/x-www-form-urlencoded;charset=utf-8",
        'App-Key': appkey, //开发者平台分配的appkey
        'Nonce': Nonce,
        'Timestamp': Timestamp,
        'Signature': SHA1HEX
    }
}
const request = require('request')
const Hashes = require('jshashes')
const SmsCode = require("../util/codes")
const Config = require("../config/")
const Util = require("../util/")
const CommonModel = require("../model/common")


const generateSignatureForCode = () => {
    const appSecret = Config.sms.appSecret;
    const Nonce = Util.createNonceStr();
    const CurTime = Util.createTimestamp();
    const SHA1 = Util.generateSHA1SignatureByHex(appSecret, Nonce, CurTime)
    return {
        Nonce: Nonce,
        CurTime: CurTime,
        SHA1: SHA1
    };
}

const getRequestSmsHeaders = function () {

    const appKey = Config.sms.appKey;
    const SignatureInfo = generateSignatureForCode()
    return {
        'Content-Type': "application/x-www-form-urlencoded;charset=utf-8",
        'AppKey': appKey, //开发者平台分配的appkey
        'Nonce': SignatureInfo.Nonce,
        'CurTime': SignatureInfo.CurTime,
        'CheckSum': SignatureInfo.SHA1
    }
}


const sendcode = async function (query) {
    let mobile = query.mobile;
    if ("register" == query.type||"bind"==query.type) {
        let _result = await CommonModel.findOne("auth", {
            where: {
                indentity_type: "1", //密码注册
                indentifier: mobile
            }
        });

        let _checkMobileResult = await CommonModel.findOne("user", {
            where: {
                mobile: mobile
            }
        });
        if (!!_result || !!_checkMobileResult) {
            return {
                status: false,
                code: -1,
                msg: "手机号已经被绑定或注册~"
            };
        }
    }


    let _resBody = {};
    let _reqUrl = "https://api.netease.im/sms/sendcode.action";
    let _reqHeaders = getRequestSmsHeaders();
    let options = {
        url: _reqUrl,
        method: "POST",
        headers: _reqHeaders,
        form: {
            templateid: 3041014,
            mobile: mobile
        }
    };
    let _res = await Util.requestService(options);
    switch (_res.code) {
        case 200:
            _resBody = {
                status: true,
                code: 0,
                msg: "发送成功",
                data: {
                    code: _res.obj,
                }
            }
            break;
        case 404:
            _resBody = {
                status: false,
                code: 100400,
                msg: "验证码过期"
            }
            break;
        case 414:
            _resBody = {
                status: false,
                code: 100414,
                msg: "缺少参数"
            }
            break;
        case 416:
            _resBody = {
                status: false,
                code: 100416,
                msg: "您发的太快啦"
            }
            break;
        case 500:
            _resBody = {
                status: false,
                code: 100500,
                msg: "短信收发服务故障"
            }
            break;
        case 413:
            _resBody = {
                status: false,
                code: 100413,
                msg: "短信验证失败"
            }
            break;
        default:
            _resBody = {
                status: false,
                code: -1,
                msg: SmsCode[_res.code] || "未知错误"
            }
            break;
    }


    return _resBody;
}

const verifycode = async function (query) {
    let mobile = query.mobile;
    let code = query.code;
    let _resBody = {};

    let _reqUrl = "https://api.netease.im/sms/verifycode.action";
    let _reqHeaders = getRequestSmsHeaders();
    let options = {
        url: _reqUrl,
        method: "POST",
        headers: _reqHeaders,
        form: {
            mobile: mobile,
            code: code
        }
    };
    let _res = await Util.requestService(options);
    switch (_res.code) {
        case 200:
            _resBody = {
                status: true,
                code: 0,
                msg: "校验成功"
            }
            break;
        case 404:
            _resBody = {
                status: false,
                code: 100400,
                msg: "验证码过期"
            }
            break;
        case 414:
            _resBody = {
                status: false,
                code: 100414,
                msg: "缺少参数"
            }
            break;
        case 416:
            _resBody = {
                status: false,
                code: 100416,
                msg: "您发的太快啦"
            }
            break;
        case 500:
            _resBody = {
                status: false,
                code: 100500,
                msg: "短信收发服务故障"
            }
            break;
        case 413:
            _resBody = {
                status: false,
                code: 100413,
                msg: "短信验证失败"
            }
            break;
        default:
            _resBody = {
                status: false,
                code: -1,
                msg: SmsCode[_res.code] || "未知错误"
            }
            break;
    }
    return _resBody;
}

const actionMap = {
    sendcode: sendcode,
    verifycode: verifycode
}


const handleAction = async(ctx, next) => {
    let req = ctx.request.fields || ctx.request.query;
    let action = req.action;

    let _resBody = await actionMap[action].call(ctx, req);

    ctx.body = _resBody;
    return next()
}


module.exports = {
    handleAction,
    sendcode,
    verifycode
}

你可能感兴趣的:(【nodejs】网易云信短信接入&融云IM-token获取)