【nodejs】網易雲信簡訊接入&融雲IM-token獲取

weixin_34185560發表於2017-03-04

網易雲信簡訊介面簽名生成方法

簡訊接入文件

1.配置

在網易雲信管理中心->應用管理->自己的應用裡檢視appkey和appsecret

84251-475e2261e9c0d996.png
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/forgeh2non/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為驗證碼
84251-5a3d1d44458a5549.png
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
}

相關文章