代码改变世界

使用七牛JS SDK中遇到的token问题

2016-03-15 13:02  Coser  阅读(1889)  评论(0)    收藏  举报

    看博客园也有些日子了,一直没写什么东西,今日闲来无事,决定写些随笔,本人非编码从业人员,一些不到之处还请大神勿喷。

    前几天注册了一个七牛账号玩玩,自己写的应用中需要网页上传功能,于是看了下七牛的文档,文档中是这样写的:

引入Plupload

  • Plupload下载,建议 2.1.1 及以上版本

  • 引入plupload.full.min.js(产品环境)或 引入plupload.dev.jsmoxie.js(开发调试)

var uploader = Qiniu.uploader({
       runtimes: 'html5,flash,html4',    //上传模式,依次退化
       browse_button: 'pickfiles',       //上传选择的点选按钮,**必需**
       uptoken_url: '/token',
            //Ajax请求upToken的Url,**强烈建议设置**(服务端提供)
        // uptoken : '<Your upload token>',
            //若未指定uptoken_url,则必须指定 uptoken ,uptoken由其他程序生成
        // unique_names: true,
            // 默认 false,key为文件名。若开启该选项,SDK会为每个文件自动生成key(文件名)
        // save_key: true,
            // 默认 false。若在服务端生成uptoken的上传策略中指定了 `sava_key`,则开启,SDK在前端将不对key进行任何处理
        domain: 'http://qiniu-plupload.qiniudn.com/',
            //bucket 域名,下载资源时用到,**必需**
        container: 'container',           //上传区域DOM ID,默认是browser_button的父元素,
        max_file_size: '100mb',           //最大文件体积限制
        flash_swf_url: 'js/plupload/Moxie.swf',  //引入flash,相对路径
        max_retries: 3,                   //上传失败最大重试次数
        dragdrop: true,                   //开启可拖曳上传
        drop_element: 'container',        //拖曳上传区域元素的ID,拖曳文件或文件夹后可触发上传
        chunk_size: '4mb',                //分块上传时,每片的体积
        auto_start: true,                 //选择文件后自动上传,若关闭需要自己绑定事件触发上传
        init: {
            'FilesAdded': function(up, files) {
                plupload.each(files, function(file) {
                    // 文件添加进队列后,处理相关的事情
                });
            },
            'BeforeUpload': function(up, file) {
                   // 每个文件上传前,处理相关的事情
            },
            'UploadProgress': function(up, file) {
                   // 每个文件上传时,处理相关的事情
            },
            'FileUploaded': function(up, file, info) {
                   // 每个文件上传成功后,处理相关的事情
                   // 其中 info 是文件上传成功后,服务端返回的json,形式如
                   // {
                   //    "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98",
                   //    "key": "gogopher.jpg"
                   //  }
                   // 参考http://developer.qiniu.com/docs/v6/api/overview/up/response/simple-response.html
                   // var domain = up.getOption('domain');
                   // var res = parseJSON(info);
                   // var sourceLink = domain + res.key; 获取上传成功后的文件的Url
            },
            'Error': function(up, err, errTip) {
                   //上传出错时,处理相关的事情
            },
            'UploadComplete': function() {
                   //队列文件处理完毕后,处理相关的事情
            },
            'Key': function(up, file) {
                // 若想在前端对每个文件的key进行个性化处理,可以配置该函数
                // 该配置必须要在 unique_names: false , save_key: false 时才生效
                var key = "";
                // do something with key here
                return key
            }
        }
});
// domain 为七牛空间(bucket)对应的域名,选择某个空间后,可通过"空间设置->基本设置->域名设置"查看获取
// uploader 为一个plupload对象,继承了所有plupload的方法,参考http://plupload.com/doc

  刚开始看这段代码的时候,一直搞不懂到底怎样上传到自己的空间,也始终以为token是一个随意定义的字符串(原谅我太无知,其实刚开始我也想到了token应该是一个效验码,就像微信公众号后台里的token一样),甚至一度以为token是上传文件后给文件定义的文件名,后台随意返回了一个guid,然后按照他说的,引入js文件,进行初始化,结果提示提供的凭证无效!

  于是开始陷入了沉思,无限审视代码,找到底是在哪里给access_key和secret_key,以至于找到了七牛官方实例文件夹下的一个叫config.js的文件,里面代码如下:

module.exports = {
    'ACCESS_KEY': '<Your Access Key>',
    'SECRET_KEY': '<Your Secret Key>',
    'Bucket_Name': '<Your Bucket Name>',
    'Port': 19110,
    'Uptoken_Url': 'uptoken',
    'Domain': 'http://qiniu-plupload.qiniudn.com/'
};

看完后我居然真的以为找到了解药,结果,还是失败...

于是又陷入了沉思...一直到看到文档中心-安全机制-上传策略里面的这样一段话:

  • AccessKeyencodedSignencodedPutPolicy:连接起来:
    uploadToken = AccessKey + ':' + encodedSign + ':' + encodedPutPolicy
    
    #假设用户的 AccessKey 为 MY_ACCESS_KEY ,则最后得到的上传凭证应为:
    uploadToken = "MY_ACCESS_KEY:wQ4ofysef1R7IKnrziqtomqyDvI=:eyJzY29wZSI6Im15LWJ1Y2tldDpzdW5mbG93ZXIuanBnIiwiZGVhZGxpbmUiOjE0NTE0OTEyMDAsInJldHVybkJvZHkiOiJ7XCJuYW1lXCI6JChmbmFtZSksXCJzaXplXCI6JChmc2l6ZSksXCJ3XCI6JChpbWFnZUluZm8ud2lkdGgpLFwiaFwiOiQoaW1hZ2VJbmZvLmhlaWdodCksXCJoYXNoXCI6JChldGFnKX0ifQ=="

    原来token使用accesskey和secret_key连接起来的...

实在懒得理解七牛的业务,便找到了后台sdk看了下,一看果然有!这里拿c#代码为例:

 Qiniu.Conf.Config.ACCESS_KEY = "Access_Key";
            Qiniu.Conf.Config.SECRET_KEY = "Secret_Key";
            IOClient target = new IOClient();
            PutExtra extra = new PutExtra();
            //设置上传的空间
            String bucket = "bucket_name";
            //设置上传的文件的key值
            String key = "yourdefinekey";

            //普通上传,只需要设置上传的空间名就可以了,第二个参数可以设定token过期时间
            PutPolicy put = new PutPolicy(bucket, 3600);

            //调用Token()方法生成上传的Token
            string upToken = put.Token();

拿到token后直接返回给前台,成功!

至此上传问题解决。总觉得七牛的文档结构貌似不太友好,希望官方以后可以修改下文档结构,不然想懒省事还真的有点难~~~