小程序 阿里云OSS 基于服務(wù)器校驗(yàn)的情況

網(wǎng)上搜了很多,發(fā)現(xiàn)小程序連接OSS是使用的 長期的OSSAccessKeyID的方案蝴韭,然后403一大堆

但是本著不給運(yùn)營大佬造成風(fēng)險(xiǎn)

不給后端大佬添麻煩的美麗愿景

直接使用自己寫移動(dòng)端的請(qǐng)求方式

記錄下這個(gè)方案

upload.js

const env = require('config.js'); //配置文件,在這文件里配置你的OSS keyId和KeySecret,timeout:87600;

const base64 = require('base64.js');//Base64,hmac,sha1,crypto相關(guān)算法

require('hmac.js');

require('sha1.js');

const Crypto = require('crypto.js');

const request  =require('request.js')

var app = getApp()

/*

*上傳文件到阿里云oss

*@param - filePath :圖片的本地資源路徑

*@param - dir:表示要傳到哪個(gè)目錄下

*@param - successc:成功回調(diào)

*@param - failc:失敗回調(diào)

*/

const uploadFile = function (filePath, dir, successc, failc) {

  if (!filePath || filePath.length < 9) {

      wx.showModal({

        title: '圖片錯(cuò)誤',

        content: '請(qǐng)重試',

        showCancel: false,

      })

      return;

  }

  console.log('上傳圖片.....');

  //圖片名字 可以自行定義,    這里是采用當(dāng)前的時(shí)間戳 + 150內(nèi)的隨機(jī)數(shù)來給圖片命名的

  const aliyunFileKey = dir + new Date().getTime() + Math.floor(Math.random() * 150) + '.png';

  const aliyunServerURL = env.uploadImageUrl;//OSS地址,需要https

  const policyBase64 = getPolicyBase64();

  console.log(app.globalData.bus.jwt)

  request.request('/user/get_upload_token',{},function(e){ //從后端獲取簽名罩句,可以用wx.request()替代

      const signature = getSignature(policyBase64,e.data.data.accessKeySecret);//獲取簽名

      wx.uploadFile({

      url: aliyunServerURL,//開發(fā)者服務(wù)器 url

      filePath: filePath,//要上傳文件資源的路徑

      name: 'file',//必須填file

      formData: {

          'key':aliyunFileKey,

          'policy':policyBase64,

          'OSSAccessKeyId':e.data.data.accessKeyId,

          'signature':signature,

          'success_action_status': '200', //不提供會(huì)204

          'x-oss-security-token':e.data.data.securityToken

      },

      success: function (res) {

          if (res.statusCode != 200) {

            failc(new Error('上傳錯(cuò)誤:' + JSON.stringify(res)))

            return;

          }

          successc(aliyunServerURL + '/'+aliyunFileKey);

      },

      fail: function (err) {

          err.wxaddinfo = aliyunServerURL;

          failc(err);

      },

    })



  },function(res){})

}

const getPolicyBase64 = function () {

  let date = new Date();

  date.setHours(date.getHours() + env.timeout);

  let srcT = date.toISOString();

  const policyText = {

      "expiration": srcT, //設(shè)置該P(yáng)olicy的失效時(shí)間,超過這個(gè)失效時(shí)間之后敛摘,就沒有辦法通過這個(gè)policy上傳文件了

      "conditions": [

        ["content-length-range", 0, 5 * 1024 * 1024] // 設(shè)置上傳文件的大小限制,5mb

      ]

  };

  const policyBase64 = base64.encode(JSON.stringify(policyText));

  return policyBase64;

}

const getSignature = function (policyBase64,security) {

  const accesskey = security;

  const bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, accesskey, {

      asBytes: true

  });

  const signature = Crypto.util.bytesToBase64(bytes);

  return signature;

}

module.exports = uploadFile;

其他相關(guān)文件

crypto.js

const Crypto = {};

(function(){

var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";


// Crypto utilities
var util = Crypto.util = {

    // Bit-wise rotate left
    rotl: function (n, b) {
        return (n << b) | (n >>> (32 - b));
    },

    // Bit-wise rotate right
    rotr: function (n, b) {
        return (n << (32 - b)) | (n >>> b);
    },

    // Swap big-endian to little-endian and vice versa
    endian: function (n) {

        // If number given, swap endian
        if (n.constructor == Number) {
            return util.rotl(n,  8) & 0x00FF00FF |
                   util.rotl(n, 24) & 0xFF00FF00;
        }

        // Else, assume array and swap all items
        for (var i = 0; i < n.length; i++)
            n[i] = util.endian(n[i]);
        return n;

    },

    // Generate an array of any length of random bytes
    randomBytes: function (n) {
        for (var bytes = []; n > 0; n--)
            bytes.push(Math.floor(Math.random() * 256));
        return bytes;
    },

    // Convert a string to a byte array
    stringToBytes: function (str) {
        var bytes = [];
        for (var i = 0; i < str.length; i++)
            bytes.push(str.charCodeAt(i));
        return bytes;
    },

    // Convert a byte array to a string
    bytesToString: function (bytes) {
        var str = [];
        for (var i = 0; i < bytes.length; i++)
            str.push(String.fromCharCode(bytes[i]));
        return str.join("");
    },

    // Convert a string to big-endian 32-bit words
    stringToWords: function (str) {
        var words = [];
        for (var c = 0, b = 0; c < str.length; c++, b += 8)
            words[b >>> 5] |= str.charCodeAt(c) << (24 - b % 32);
        return words;
    },

    // Convert a byte array to big-endian 32-bits words
    bytesToWords: function (bytes) {
        var words = [];
        for (var i = 0, b = 0; i < bytes.length; i++, b += 8)
            words[b >>> 5] |= bytes[i] << (24 - b % 32);
        return words;
    },

    // Convert big-endian 32-bit words to a byte array
    wordsToBytes: function (words) {
        var bytes = [];
        for (var b = 0; b < words.length * 32; b += 8)
            bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
        return bytes;
    },

    // Convert a byte array to a hex string
    bytesToHex: function (bytes) {
        var hex = [];
        for (var i = 0; i < bytes.length; i++) {
            hex.push((bytes[i] >>> 4).toString(16));
            hex.push((bytes[i] & 0xF).toString(16));
        }
        return hex.join("");
    },

    // Convert a hex string to a byte array
    hexToBytes: function (hex) {
        var bytes = [];
        for (var c = 0; c < hex.length; c += 2)
            bytes.push(parseInt(hex.substr(c, 2), 16));
        return bytes;
    },

    // Convert a byte array to a base-64 string
    bytesToBase64: function (bytes) {

        // Use browser-native function if it exists
        if (typeof btoa == "function") return btoa(util.bytesToString(bytes));

        var base64 = [],
            overflow;

        for (var i = 0; i < bytes.length; i++) {
            switch (i % 3) {
                case 0:
                    base64.push(base64map.charAt(bytes[i] >>> 2));
                    overflow = (bytes[i] & 0x3) << 4;
                    break;
                case 1:
                    base64.push(base64map.charAt(overflow | (bytes[i] >>> 4)));
                    overflow = (bytes[i] & 0xF) << 2;
                    break;
                case 2:
                    base64.push(base64map.charAt(overflow | (bytes[i] >>> 6)));
                    base64.push(base64map.charAt(bytes[i] & 0x3F));
                    overflow = -1;
            }
        }

        // Encode overflow bits, if there are any
        if (overflow != undefined && overflow != -1)
            base64.push(base64map.charAt(overflow));

        // Add padding
        while (base64.length % 4 != 0) base64.push("=");

        return base64.join("");

    },

    // Convert a base-64 string to a byte array
    base64ToBytes: function (base64) {

        // Use browser-native function if it exists
        if (typeof atob == "function") return util.stringToBytes(atob(base64));

        // Remove non-base-64 characters
        base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");

        var bytes = [];

        for (var i = 0; i < base64.length; i++) {
            switch (i % 4) {
                case 1:
                    bytes.push((base64map.indexOf(base64.charAt(i - 1)) << 2) |
                               (base64map.indexOf(base64.charAt(i)) >>> 4));
                    break;
                case 2:
                    bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0xF) << 4) |
                               (base64map.indexOf(base64.charAt(i)) >>> 2));
                    break;
                case 3:
                    bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0x3) << 6) |
                               (base64map.indexOf(base64.charAt(i))));
                    break;
            }
        }

        return bytes;

    }

};

// Crypto mode namespace
Crypto.mode = {};

})();

module.exports = Crypto;

base64


var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64DecodeChars = new Array(
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
    -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
function encode(str) {
    var out, i, len;
    var c1, c2, c3;
    len = str.length;
    i = 0;
    out = "";
    while (i < len) {
        c1 = str.charCodeAt(i++) & 0xff;
        if (i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt((c1 & 0x3) << 4);
            out += "==";
            break;
        }
        c2 = str.charCodeAt(i++);
        if (i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
            out += base64EncodeChars.charAt((c2 & 0xF) << 2);
            out += "=";
            break;
        }
        c3 = str.charCodeAt(i++);
        out += base64EncodeChars.charAt(c1 >> 2);
        out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
        out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
        out += base64EncodeChars.charAt(c3 & 0x3F);
    }
    return out;
}
function decode(str) {
    var c1, c2, c3, c4;
    var i, len, out;
    len = str.length;
    i = 0;
    out = "";
    while (i < len) {
        /* c1 */
        do {
            c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
        } while (i < len && c1 == -1);
        if (c1 == -1)
            break;
        /* c2 */
        do {
            c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
        } while (i < len && c2 == -1);
        if (c2 == -1)
            break;
        out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
        /* c3 */
        do {
            c3 = str.charCodeAt(i++) & 0xff;
            if (c3 == 61)
                return out;
            c3 = base64DecodeChars[c3];
        } while (i < len && c3 == -1);
        if (c3 == -1)
            break;
        out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
        /* c4 */
        do {
            c4 = str.charCodeAt(i++) & 0xff;
            if (c4 == 61)
                return out;
            c4 = base64DecodeChars[c4];
        } while (i < len && c4 == -1);
        if (c4 == -1)
            break;
        out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
    }
    return out;
}


function utf16to8(str) {
    var out, i, len, c;
    out = "";
    len = str.length;
    for (i = 0; i < len; i++) {
        c = str.charCodeAt(i);
        if ((c >= 0x0001) && (c <= 0x007F)) {
            out += str.charAt(i);
        } else if (c > 0x07FF) {
            out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
            out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
            out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
        } else {
            out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
            out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
        }
    }
    return out;
}
function utf8to16(str) {
    var out, i, len, c;
    var char2, char3;
    out = "";
    len = str.length;
    i = 0;
    while (i < len) {
        c = str.charCodeAt(i++);
        switch (c >> 4) {
            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                // 0xxxxxxx
                out += str.charAt(i - 1);
                break;
            case 12: case 13:
                // 110x xxxx 10xx xxxx
                char2 = str.charCodeAt(i++);
                out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
                break;
            case 14:
                // 1110 xxxx 10xx xxxx 10xx xxxx
                char2 = str.charCodeAt(i++);
                char3 = str.charCodeAt(i++);
                out += String.fromCharCode(((c & 0x0F) << 12) |
                    ((char2 & 0x3F) << 6) |
                    ((char3 & 0x3F) << 0));
                break;
        }
    }
    return out;
}


module.exports = {
    encode: encode,
    decode: decode,
    utf16to8: utf16to8,
    utf8to16: utf8to16
}

hmac.js

const Crypto = require('./crypto.js');

(function(){

// Shortcut
var util = Crypto.util;

Crypto.HMAC = function (hasher, message, key, options) {

    // Allow arbitrary length keys
    key = key.length > hasher._blocksize * 4 ?
          hasher(key, { asBytes: true }) :
          util.stringToBytes(key);

    // XOR keys with pad constants
    var okey = key,
        ikey = key.slice(0);
    for (var i = 0; i < hasher._blocksize * 4; i++) {
        okey[i] ^= 0x5C;
        ikey[i] ^= 0x36;
    }

    var hmacbytes = hasher(util.bytesToString(okey) +
                           hasher(util.bytesToString(ikey) + message, { asString: true }),
                           { asBytes: true });
    return options && options.asBytes ? hmacbytes :
           options && options.asString ? util.bytesToString(hmacbytes) :
           util.bytesToHex(hmacbytes);

};

})();

module.exports = Crypto;

util.js

const formatTime = date => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()

  return [year, month, day].map(formatNumber).join('/') + 'T' + [hour, minute, second].map(formatNumber).join(':')
}

const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : '0' + n
}

module.exports = {
  formatTime: formatTime
}

config.js

var fileHost = "https://****.oss-cn-beijing.aliyuncs.com";//你的阿里云OSS地址  在你當(dāng)前小程序的公眾號(hào)后臺(tái)的uploadFile 合法域名也要配上這個(gè)域名
var config = {
   uploadImageUrl: `${fileHost}`, // 默認(rèn)存在根目錄,可根據(jù)需求改
   bucketName:'corgi-pic',  // AccessKeyId 去你的阿里云上控制臺(tái)上找
   timeout: 80000 //這個(gè)是上傳文件時(shí)Policy的失效時(shí)間
};

module.exports = config

下面使用它乳愉,前面的所有我都放在了utils文件夾里

 addPic:function(){ //bindtap時(shí)間
    var that = this
    wx.chooseImage({
      count:9,
      complete: (res) => {
        var tempFilePaths = res.tempFilePaths;
        var nowTime = util.formatTime(new Date());
        //支持多圖上傳
        for (var i = 0; i < res.tempFilePaths.length; i++) {
           //顯示消息提示框
           wx.showLoading({
              title: '上傳中' + (i + 1) + '/' + res.tempFilePaths.length,
              mask: true
           })
           //上傳圖片
           //你的域名下的/cbb文件下的/當(dāng)前年月日文件下的/圖片.png
           //圖片路徑可自行修改
           uploadImage(res.tempFilePaths[i], 'bus/' + nowTime + '/',
              function (result) {
                 console.log("======上傳成功圖片地址為:", result);
                 that.addBusPic(result); //不重要兄淫,處理結(jié)果的方法
                 wx.hideLoading();
              }, function (result) {
                 console.log("======上傳失敗======", result);
                 //做你具體的業(yè)務(wù)邏輯操作
                 if(length==res.tempFilePaths.length){
                  
                }
                 wx.hideLoading()
              })
            }
      },
    })  

  },


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蔓姚,隨后出現(xiàn)的幾起案子捕虽,更是在濱河造成了極大的恐慌,老刑警劉巖坡脐,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泄私,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)晌端,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門捅暴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人咧纠,你說我怎么就攤上這事蓬痒。” “怎么了漆羔?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵梧奢,是天一觀的道長。 經(jīng)常有香客問我演痒,道長亲轨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任鸟顺,我火速辦了婚禮惦蚊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诊沪。我一直安慰自己养筒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布端姚。 她就那樣靜靜地躺著晕粪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪渐裸。 梳的紋絲不亂的頭發(fā)上巫湘,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音昏鹃,去河邊找鬼尚氛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛洞渤,可吹牛的內(nèi)容都是我干的阅嘶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼载迄,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼讯柔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起护昧,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤魂迄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后惋耙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捣炬,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熊昌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了湿酸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片婿屹。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖稿械,靈堂內(nèi)的尸體忽然破棺而出选泻,到底是詐尸還是另有隱情,我是刑警寧澤美莫,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布页眯,位于F島的核電站,受9級(jí)特大地震影響厢呵,放射性物質(zhì)發(fā)生泄漏窝撵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一襟铭、第九天 我趴在偏房一處隱蔽的房頂上張望碌奉。 院中可真熱鬧,春花似錦寒砖、人聲如沸赐劣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽魁兼。三九已至,卻和暖如春漠嵌,著一層夾襖步出監(jiān)牢的瞬間咐汞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工儒鹿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留化撕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓约炎,卻偏偏與公主長得像植阴,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子圾浅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359