其他人上传到我的文件夹的保管箱访问令牌

Posted

技术标签:

【中文标题】其他人上传到我的文件夹的保管箱访问令牌【英文标题】:dropbox access token for others to upload to my folder 【发布时间】:2013-12-08 11:40:12 【问题描述】:

我计划让一个服务器程序获取我的保管箱帐户访问令牌并传递给

客户端程序上传到我的保管箱文件夹。客户端不需要数据库帐户或登录,并且能够将文件发送到我的数据库文件夹(因此不使用 OAuth ...)。类似于:

this 和this

但没有用户先上传到服务器,即一旦用户获得访问令牌,他们就直接上传到数据库。

我尝试使用 Apache httpclient 4.3 来模拟浏览器来执行获取请求令牌、发送登录信息以获取访问令牌,但在通过 post 将文件上传到表单时卡住了。错误是 HTTP 400 Bad Request ...



    executing request:GET https://www.dropbox.com/login HTTP/1.1
    ----------------------------------------
    HTTP/1.1 200 OK
    Request Token: moiejtzdLqTA_0sh3gQyNZAI

    executing request:POST https://www.dropbox.com/login HTTP/1.1
    ----------------------------------------
    HTTP/1.1 200 OK
    Access Token: 5Ot52QKDbDPSsL1ApU4MIapJ

    executing request:POST https://dl-web.dropbox.com/upload?

    name=sample.jpg&dest=upload&cookie_t=5Ot52QKDbDP....SsJ&t=5Ot5...apJ HTTP/1.1
    ----------------------------------------
    HTTP/1.1 400 Bad Request

我在登录和上传文件时使用 Firefox LiveHttpHeader 来捕获标头,并看到文件上传实际上是这样做的(并反映在代码中):



https://dl-web.dropbox.com/chunked_upload?
  name=tmp1.jpg
  &chunk=0
  &chunks=1
  &bjar=W3sic2Vzc1..............Q%253D%253D
  &blid=AAAw4tn................2cDxA
  &cookie_t=32yq........nw6c34o
  &dest=
  &t=32yqVof........c34o
  &reported_total_size=5611
  &upload_id=1BKGRRP5TpCEjcWSu5tmpQ
  &offset=0

所以显然我错过了一些参数,但不知道是什么。访问令牌似乎是有效的,因为我可以在从 httpclinet 帖子到https://www.dropbox.com/home 的返回中看到我的帐户信息,但上传根本不起作用。任何人都有类似的经验并收到 HTTP 400 错误? .... 非常感谢!

部分代码如下:

构造函数和main():



    // constructor ...
        public HttpClientExample() 
            gcookies = new BasicCookieStore();  
            globalConfig = RequestConfig.custom()
                    .setCookieSpec(CookieSpecs.BEST_MATCH)
                    .build();

            // Create local HTTP context
            ghttpContext = HttpClientContext.create(); 
            ghttpContext.setCookieStore(gcookies);

            //
            redirectStrategy = new LaxRedirectStrategy();  // for http redirect ...
            httpclient = HttpClients.custom()   
                    .setDefaultRequestConfig(this.globalConfig)
                    .setDefaultCookieStore(this.gcookies)
                    .setRedirectStrategy(redirectStrategy)
                    .build();       
          // constructor ...

        public static void main(String[] args) throws Exception 

            HttpClientExample myhttp = new HttpClientExample();
            try 

                    this.localConfig = RequestConfig.copy(this.globalConfig)
                    .setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY)
                    .build();

                String requestToken = this.getRequestToken(httpclient, loginurl);

                theAccessToken = this.postForAccessToken(requestToken, loginurl);

                String localFileTopassIn = this.localPath ;
                this.postToUpload(httpclient, this.theAccessToken, localFileTopassIn , this.dropboxFolderOnlyName);


            

        

获取请求令牌:



private String getRequestToken(HttpClient client, String theURL) throws Exception 
    HttpGet httpget = new HttpGet(theURL);
    httpget.setConfig(localConfig);     
    httpget.setHeader("Connection", "keep-alive");

    System.out.println("\nexecuting request:" + httpget.getRequestLine());


    // Create a custom response handler
    ResponseHandler responseHandler = new ResponseHandler() 

        public String handleResponse(final HttpResponse response)
                           throws ClientProtocolException, IOException 
            int status = response.getStatusLine().getStatusCode();
            if (status >= 200 )  // && status  cookies = gcookies.getCookies();
    for (Cookie aCookie: cookies) 
        String cookieName = aCookie.getName();
        if ( !(cookieName.lastIndexOf(gvcString) == -1) ) 
            gvc = aCookie.getValue();
         else if ( !(cookieName.lastIndexOf(tString) == -1) ) 
            requestToken = aCookie.getValue();
        
    

    System.out.println("Request Token: " + requestToken );
    return  requestToken;           



postForAccessToken:



private String postForAccessToken(HttpClient client, String requestToken, String theURL) throws Exception
    /*
     *  Send a post together with request token and my login to get accessToken ...
     */
    HttpPost httppost = new HttpPost(theURL); // loginurl);
    httppost.setConfig(localConfig);
    ghttpContext.setCookieStore(gcookies);

    List params = new LinkedList();
    params.add(new BasicNameValuePair("login_email", myemail));
    params.add(new BasicNameValuePair("login_password", mypasswd));
    params.add(new BasicNameValuePair("t", requestToken));

    HttpEntity postentity = new UrlEncodedFormEntity(params); 
    httppost.setEntity(postentity); 

    System.out.println("\nexecuting request:" + httppost.getRequestLine());

    // Create a custom response handler
    ResponseHandler responseHandler = new ResponseHandler() 

        public String handleResponse(final HttpResponse response)
                           throws ClientProtocolException, IOException 
            int status = response.getStatusLine().getStatusCode();
            if (status >= 200 )  // && status  cookies = gcookies.getCookies();
    for (Cookie aCookie: cookies) 
        String cookieName = aCookie.getName();
        if ( !(cookieName.lastIndexOf(tString) == -1) ) 
            theAccessToken = aCookie.getValue();
        
    

    System.out.println("Access Token: " + theAccessToken );     
    return theAccessToken;
   

postToUpload:

私有字符串 postToUpload(HttpClient 客户端,字符串 accessToken,字符串 localFileInfo,字符串 destPath)抛出异常 字符串 bjarString = "bjar"; 字符串 blidString = "blid"; 字符串 bjar=null; 字符串盲=空; 列出 cookie = gcookies.getCookies(); for (Cookie aCookie: cookies) 字符串 cookieName = aCookie.getName(); if ( !(cookieName.lastIndexOf(bjarString) == -1) ) bjar = aCookie.getValue(); else if ( !(cookieName.lastIndexOf(blidString) == -1) ) blid = aCookie.getValue(); String[] fileNameArry = localFileInfo.split("(\\\\|/)"); 字符串文件名 = fileNameArry[fileNameArry.length - 1]; // 获取最后一部分 ... URI uri = 新的 URIBuilder() .setScheme("https") .setHost("dl-web.dropbox.com") .setPath("/上传") .setParameter("名称", 文件名) .setParameter("dest", destPath) .setParameter("cookie_t", accessToken) .setParameter("t", accessToken) 。建造(); HttpPost httppost = 新的 HttpPost(uri); httppost.setConfig(localConfig); ghttpContext.setCookieStore(gcookies); FileBody bin = new FileBody(new File(localFileInfo)); StringBody comment = new StringBody("某种二进制文件", ContentType.DEFAULT_BINARY); HttpEntity reqEntity = MultipartEntityBuilder.create() .addPart("bin", bin) .addPart(“评论”,评论) 。建造(); httppost.setEntity(reqEntity); // 添加标题 httppost.setHeader("主机", "www.dropbox.com"); httppost.setHeader("用户代理", USER_AGENT); httppost.setHeader("接受", "文本/html,应用程序/xhtml+xml,应用程序/xml;q=0.9,*/*;q=0.8"); httppost.setHeader("连接", "保持活动"); httppost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); httppost.setHeader("Pragma", "no-cache"); httppost.setHeader("缓存控制", "无缓存"); // 添加实体 System.out.println("\n执行请求:" + httppost.getRequestLine()); // 创建自定义响应处理程序 ResponseHandler responseHandler = new ResponseHandler() 公共字符串句柄响应(最终的 HttpResponse 响应) 抛出 ClientProtocolException,IOException int status = response.getStatusLine().getStatusCode(); if (status >= 200 ) // && 状态

【问题讨论】:

【参考方案1】:

OAuth 是使用 Dropbox API 的唯一方法。一旦你有一个 OAuth 访问令牌(你通过一次身份验证获得,在这种情况下使用你的帐户),你只需要使用标头 Authorization: Bearer <token> 和文件内容在身体。

请注意,任何拥有您的访问令牌的人也可以删除您的所有文件、上传他们的个人 DVD 收藏等。因此不建议您共享该访问令牌。

【讨论】:

关于头部授权的部分:Bearer 非常有用,对于 GET 请求也是如此。 Dropbox 在其文档中的任何地方都没有提到这一点。 这只是标准的 OAuth 2。(任何使用 OAuth 2 的 API 的工作方式都是一样的。)但我们会努力在文档中指出这一点。【参考方案2】:

有files_get_temporary_upload_link:

获取一次性使用的临时上传链接,将文件上传到 Dropbox 位置。 此端点充当延迟上传。返回的临时上传链接可用于对要上传的数据进行 POST 请求。然后将使用先前提供给 get_temporary_upload_link 但仅在消费时评估的 CommitInfo 执行上传。因此,与用户 Dropbox 状态相关的无效 CommitInfo 导致的错误只会在消费时传达。此外,这些错误作为通用 HTTP 409 冲突响应浮出水面,可能隐藏问题详细信息。最长临时上传链接持续时间为 4 小时。在消费或到期时,必须生成一个新链接。在任何给定时间,特定上传路径可能存在多个链接。

所以你需要一个访问令牌来调用这个函数,但是上传者只需要生成的 URL,不能访问 Dropbox 保险库的其余部分。

【讨论】:

以上是关于其他人上传到我的文件夹的保管箱访问令牌的主要内容,如果未能解决你的问题,请参考以下文章

Dropbox 直接从浏览器上传文件

无法使用保管箱 API 将文件(使用 ALAsset 库)上传到保管箱

如何显示上传到我的 ftp 文件夹的图像

将大文件上传到服务器时,OAuth 访问令牌已过期

通过 API 访问 OneDrive 个人保管库

模型 URN 安全问题