Skip to main content
 首页 » 编程设计

python之在 Safari 中使用 Twython 获取授权 token 时出现问题

2025年05月04日8Renyi-Fan

我正在使用 Twython 为我用 Django 构建的网站实现 OAuth 功能。我希望用户能够使用他们的 Twitter 凭据注册和登录。

我通过稍微调整 Twython Git 存储库中的示例创建了用于登录和注册 Twitter 信息的基本 View 。

我的问题是用户目前可以在 Firefox 和 Chrome 中使用 Twitter OAuth 进行注册,但不能在 Safari 中进行注册。我对实现此功能的看法是:

def begin_auth(request): 
        twitter = Twython( 
        twitter_token = TWITTER_KEY, 
        twitter_secret = TWITTER_SECRET, 
        callback_url = request.build_absolute_uri(reverse('portnoy.views.thanks')) 
    ) 
    # Request an authorization url to send the user to... 
    auth_props = twitter.get_authentication_tokens() 
 
    # Then send them over there, durh. 
    request.session['request_token'] = auth_props 
    return HttpResponseRedirect(auth_props['auth_url']) 
 
def thanks(request, redirect_url='/'): 
     c = RequestContext(request) 
     twitter = Twython( 
         twitter_token = TWITTER_KEY, 
         twitter_secret = TWITTER_SECRET, 
         oauth_token = request.session['request_token']['oauth_token'], 
         oauth_token_secret = request.session['request_token']['oauth_token_secret'] 
     ) 
 
    # Retrieve the tokens we want... 
    authorized_tokens = twitter.get_authorized_tokens() 
    request.session['request_tokens'] = authorized_tokens 
    debug('thanks', request.session['request_tokens']) 
 
    user = User.objects.filter(username=authorized_tokens['screen_name']) 
    if user.exists(): 
        user = user[0] 
        user.backend='django.contrib.auth.backends.ModelBackend'      
        auth.login(request,user) 
    else: 
        return render_to_response('twitter_register.html', c)    
    return HttpResponseRedirect(redirect_url) 

在第二个 View 中,谢谢,我获取 authorized_tokens 并将它们存储在 session 中,因此可以在未注册用户被定向到的 twitter_register.html 页面中轻松访问它们,从而允许未注册用户使用他们的 Twitter 进行注册信息。

下面提供了在 Safari 中直到失败行的 twitter_register View 代码:

def twitter_register(request): 
    c = RequestContext(request) 
    if request.method == 'POST': 
        email = request.POST.get('email') 
    password = request.POST.get('password') 
    if not SafeContact.objects.filter(email=email).exists(): 
        return HttpResponseRedirect('/') 
    if (User.objects.filter(email=email).exists()): 
        c['warning'] = "Looks like that email is already in use" 
        return render_to_response('twitter_register.html', c)  
    #debug('twitter_register', request.session['request_tokens']) 
    twitter = Twython( 
        twitter_token = TWITTER_KEY, 
        twitter_secret = TWITTER_SECRET, 
        oauth_token = request.session['request_tokens']['oauth_token'], 
        oauth_token_secret = request.session['request_tokens']['oauth_token_secret'] 
    ) 
    debug('twitter_register', request.session['request_tokens']) 
    twitter_user_dict = twitter.showUser(screen_name=request.session['request_tokens']['screen_name']) 

所有这些在 Firefox 和 Chrome 中都有效,但在 Safari 中失败。特别是,在 Safari 中,此代码在最后提供的 twitter_register 行上失败:

twitter.showUser(screen_name=request.session['request_tokens']['screen_name']).  

产生以下错误:

The error is KeyError: 'screen_name'. 

调试语句 debug('thanks', request.session['request_tokens']) 在 Firefox 和 Chrome 中按预期打印 authorized_tokens,但出于某种原因在 Safari 中打印 2x。第一次打印时,它会按预期显示授权 token 的字典,但在第二次打印时,它会显示

thanks: {'<?xml version': '"1.0" encoding="UTF-8"?>\\n<hash>\\n  <error>Invalid / expired Token</error>\\n  <request>/oauth/access_token</request>\\n</hash>\\n'} 

我很困惑,因为这似乎只发生在 Safari 中(我正在测试 v. 5.1.5)。

如有任何关于如何解决此问题的建议,我们将不胜感激。感谢您花时间看这个!

请您参考如下方法:

似乎“thanks” View 被执行了两次。

是否可能是您的 twitter_register View 中的以下几行导致了它?

if not SafeContact.objects.filter(email=email).exists(): 
        return HttpResponseRedirect('/')