【问题标题】:Dropbox Python API Authentication failed And Request Token Not FoundDropbox Python API 身份验证失败并且未找到请求令牌
【发布时间】:2014-07-06 20:39:55
【问题描述】:

这是我收到错误“身份验证失败”的部分。 我正在开发一个 Web 应用程序,我需要一些帮助。我正在为土耳其书籍开发像 Project Gutenberg 这样的网络应用程序,并且我想添加“添加到我的 Dropbox”功能,就像在 Project Gutenberg 中一样。我正在使用 Django 作为 Web 框架,这就是我到目前为止所做的。 (请记住,我是 Django 的绝对初学者和初级软件开发人员,因此任何有关 Django 最佳实践或安全问题的建议也会有所帮助。)

这是来自 book_detail.html

<div>
   <form action="/booksite/dropbox_integration/{{book.id}}/" method="post">{% csrf_token %}
       <input type="submit" value="Add to Dropbox" />
   </form>
</div>

这是我的 dropbox_integration 视图:

def dropbox_integration(request, book_id):
if request.method == 'POST':
    APP_KEY = 'xxxxxx'  # I have the real values of key and secret in the code
    APP_SECRET = 'xxxxx'
    ACCESS_TYPE = 'app_folder'
    #This is my redirect url after login and upload file
    callback = "http://localhost:8000/booksite/file_upload"

    sess = session.DropboxSession(APP_KEY, APP_SECRET, ACCESS_TYPE)
    request_token = sess.obtain_request_token()
    url = sess.build_authorize_url(request_token, oauth_callback=callback)
    #i use session for parameter passing but now this line is useless and irrelevant
    request.session['book_id']=book_id

    return HttpResponseRedirect(url)
return HttpResponseRedirect("http://localhost:8000/booksite/")

这是我的 file_upload 视图:

def file_upload(request):
APP_KEY = 'xxx' # i got real key and secret
APP_SECRET = 'xxxx'
ACCESS_TYPE = 'app_folder'

sess = session.DropboxSession(APP_KEY, APP_SECRET, ACCESS_TYPE)
b_id=request.session['book_id']

#this line is useless now
book = get_object_or_404(Book, pk=1) #book_id
#i want to upload this file to my dropbox as foo1.pdf
f = open('C:/Users/baris/workspace/OpenLibrary/booksite/temp_files/documents/docs/201462912729dt_kitap1.pdf', 'rb')


client1 = client.DropboxClient(sess)
r1 = client1.put_file('foo1.pdf', f)
url="http://localhost:8000/booksite"
return HttpResponseRedirect(url)  

我单击“添加到 Dropbox”按钮。它会将我重定向到保管箱,然后我输入凭据。 Dropbox 询问我是否想通过按钮允许和拒绝授予对我的网站(我的应用程序)的权限。我点击拒绝。页面正在加载,加载,加载...我收到错误:

Exception Type:     ErrorResponse
Exception Value:    [401] u'Authentication failed'
Django Version:     1.6.5
Request URL:    http://localhost:8000/booksite/file_upload?oauth_token=some_real_token&uid=some_number

谢谢,提前。

2014 年 7 月 7 日更新

这是我收到错误“未找到请求令牌”的部分。

这是 dropbox_integration 视图:

def dropbox_integration(request, book_id):
    APP_KEY = 'xxx' #i got real values
    APP_SECRET = 'xxx'
    ACCESS_TYPE = 'app_folder'

    if request.method == 'POST':
        base_path=os.path.dirname(os.path.abspath(__file__))
        config_path=os.path.join(os.path.join(base_path, 'temp_files'), "config.txt")
        logger.debug("Base path="+base_path)
        logger.debug("Config path="+config_path)
        content=[]
        if os.path.exists(config_path):
            logger.debug("Config.txt var")
            with open(config_path) as the_file:
                content = the_file.readlines()
        else:
            logger.debug("Config.txt yok")
            with open(config_path, 'w') as the_file:
                the_file.write(APP_KEY)
                the_file.write('|')
                the_file.write(APP_SECRET)

        config_key=content[0].split('|')[0]
        config_secret=content[0].split('|')[1]

        callback = "http://127.0.0.1:8000/booksite/file_upload"

        sess = session.DropboxSession(config_key, config_secret, ACCESS_TYPE)
        request_token = sess.obtain_request_token()
        request.session['request_token']=json.dumps(request_token.__dict__)
        logger.debug("req_ses="+request.session['request_token'])

        url = sess.build_authorize_url(request_token, oauth_callback=callback)

        request.session['book_id']=book_id

        return HttpResponseRedirect(url)
    return HttpResponseRedirect("http://127.0.0.1:8000/booksite/")

这是 file_upload 视图:

@csrf_protect   
def file_upload(request):
    base_path = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(os.path.join(base_path, 'temp_files'), "config.txt")
    logger.debug("Base path=" + base_path)
    logger.debug("Config path=" + config_path)
    content = []
    if os.path.exists(config_path):
        with open(config_path) as the_file:
           content = the_file.readlines()
    else:
        logger.debug("Config.txt dosyasi bulunamadi.")

    config_key = content[0].split('|')[0]
    config_secret = content[0].split('|')[0]

    ACCESS_TYPE = 'app_folder'

    sess = session.DropboxSession(config_key, config_secret, ACCESS_TYPE)
    b_id = request.session['book_id']
    logger.debug("File upload fonksiyonu book id=" + str(b_id))

    book = get_object_or_404(Book, pk=1)  # book_id olarak 1 verdim.
    request_token = JSONDecoder(object_hook=from_json).decode(request.session['request_token'])
    logger.debug("REQUEST_TOKEN="+str(request_token))
    access_token = sess.obtain_access_token(request_token)
    logger.debug(access_token)
    client1 = client.DropboxClient(sess)
    try:
        base_path1 = os.path.dirname(os.path.abspath(__file__))
        with open(os.path.join(base_path1, "udacity.txt"), "rb") as fh:  # os.path.join(self.path, self.filename)
             path = os.path.join(path, filename)
             print path
             print fh
             res = client1.put_file("udacity.txt", fh)
    except Exception, e:
        logger.debug("ERROR: " + str(e))

    url = "http://127.0.0.1:8000/booksite/books/12/detail/"
    return HttpResponseRedirect(url) 

这是我的助手 from_json 函数:

def from_json(json_object):
    secret=""
    key=""
    if 'secret' in json_object:
        secret=json_object['secret']
    if 'key' in json_object:
        key=json_object['key']
    logger.debug(secret+" ---- "+key)
    return session.OAuthToken(json_object['secret'], json_object['key'])

我在 file_upload 视图中的 sess.obtain_access_token(request_token) 行收到错误。 我无法获取 access_token 并收到错误“未找到请求令牌”。是什么原因? 这是我的 Django 日志:

[06/Jul/2014 15:38:15] DEBUG [booksite.views:133] File upload function book id=12
[06/Jul/2014 15:38:15] DEBUG [booksite.views:164] xxxxx---- xxxx
[06/Jul/2014 15:38:15] DEBUG [booksite.views:137] REQUEST_TOKEN=<dropbox.session.OAuthToken object at 0x028BCB90>

【问题讨论】:

  • “未找到请求令牌”错误消息是 Dropbox 服务器告诉您它无法识别您传递的请求令牌值,因此为了排除故障,我将首先手动检查request_token 对象上的实际密钥和秘密值是您所期望的。 (例如,将密钥与您授权应用程序的 /authorize URL 中的密钥进行比较)
  • 谢谢。请求令牌、访问令牌、密钥、秘密等概念确实令人困惑。我想我需要从理论上的 oauth 教程开始,因为我被困了几天。
  • 这里有一个基本教程可能有助于理解这些概念:dropbox.com/developers/blog/20/using-oauth-in-plaintext-mode

标签: python django dropbox dropbox-api


【解决方案1】:

可能错误是因为 Django 找不到您在表单中使用的{% csrf_token %}跨站点请求伪造保护。当然,出于安全原因,您必须添加它...

要为跨站点请求伪造添加安全性,您必须将以下装饰器添加到您的视图中:

from django.views.decorators.csrf import csrf_exempt, csrf_protect

@csrf_protect
#@csrf_exempt says to make an exemption on csrf, but of course is not secure.
#@csrf_exempt
def file_upload(request):
    ...

更多详情请阅读Django Documentation

【讨论】:

  • 感谢您的帮助。我试过了,但与 Dropbox api 相关的代码中还有另一个问题。我正在更新我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
  • 2018-07-23
  • 2020-03-06
  • 2021-11-23
  • 1970-01-01
相关资源
最近更新 更多