2016-09-11 41 views
0

我正在嘗試在我的登錄頁面添加twitter重定向登錄。這就是所謂的login.html。werkzeug.routing.BuildError BuildError :('oauth_authorize',{'provider':'twitter'},None)

<li><a href="{{ url_for('oauth_authorize', provider='twitter') }}">Login with Twitter</a></li> 

點擊該URL後,它會拋出BUILDERROR。

BuildError: ('oauth_callback', {'provider': 'twitter'}, None) 

這是代碼。

@user_blueprint.route('/authorize/<provider>') 
def oauth_authorize(provider): 
    if not current_user.is_anonymous: 
     return rredirect(url_for('main.home')) 
    oauth = OAuthSignIn.get_provider(provider) 
    return oauth.authorize() 

這是我的views.py oauth_authorize函數。 @ user_blueprint.route( '/回調/')

def oauth_callback(provider): 
    if not current_user.is_anonymous: 
     return redirect(url_for('main.home')) 
    oauth = OAuthSignIn.get_provider(provider) 
    social_id, username, email = oauth.callback() 
    if social_id is None: 
     flash('Authentication failed.') 
     return redirect(url_for('user.login')) 
    user = User.query.filter_by(social_id=social_id).first() 
    if not user: 
     user = UserProfile(social_id=social_id, nickname=username, email=email) 
     db.session.add(user) 
     db.session.commit() 
    login_user(user, True) 
    return redirect(url_for('user.login')) 

我一直在試圖調試問題。 我對我所擁有的oauth.py代碼有着複雜的感受。

from rauth import OAuth1Service, OAuth2Service 
from flask import current_app, url_for, request, redirect, session 


class OAuthSignIn(object): 
    providers = None 

    def __init__(self, provider_name): 
     self.provider_name = provider_name 
     credentials = current_app.config['OAUTH_CREDENTIALS'][provider_name] 
     self.consumer_id = credentials['id'] 
     self.consumer_secret = credentials['secret'] 

    def authorize(self): 
     pass 

    def callback(self): 
     pass 

    def get_callback_url(self): 
     return url_for('oauth_callback', provider=self.provider_name, 
         _external=True) 

    @classmethod 
    def get_provider(self, provider_name): 
     if self.providers is None: 
      self.providers = {} 
      for provider_class in self.__subclasses__(): 
       provider = provider_class() 
       self.providers[provider.provider_name] = provider 
     return self.providers[provider_name] 


class FacebookSignIn(OAuthSignIn): 
    def __init__(self): 
     super(FacebookSignIn, self).__init__('facebook') 
     self.service = OAuth2Service(
      name='facebook', 
      client_id='512038548997732', 
      client_secret='a5a480e8da592d5c16feeee5426976b4', 
      authorize_url='https://graph.facebook.com/oauth/authorize', 
      access_token_url='https://graph.facebook.com/oauth/access_token', 
      base_url='https://graph.facebook.com/' 
     ) 

    def authorize(self): 
     return redirect(self.service.get_authorize_url(
      scope='email', 
      response_type='code', 
      redirect_uri=self.get_callback_url()) 
     ) 

    def callback(self): 
     if 'code' not in request.args: 
      return None, None, None 
     oauth_session = self.service.get_auth_session(
      data={'code': request.args['code'], 
        'grant_type': 'authorization_code', 
        'redirect_uri': self.get_callback_url()} 
     ) 
     me = oauth_session.get('me?fields=id,email').json() 
     return (
      'facebook$' + me['id'], 
      me.get('email').split('@')[0], # Facebook does not provide 
              # username, so the email's user 
              # is used instead 
      me.get('email') 
     ) 


class TwitterSignIn(OAuthSignIn): 
    def __init__(self): 
     super(TwitterSignIn, self).__init__('twitter') 
     self.service = OAuth1Service(
      name='twitter', 
      consumer_key='pNU7LEHOLEAJH3lQRNwOjiJMH', 
      consumer_secret='WFe5DVdi5JZ6KtuyRWYP9BkC8905EUp0N56junLtde1vL5w2NR', 
      request_token_url='https://api.twitter.com/oauth/request_token', 
      authorize_url='https://api.twitter.com/oauth/authorize', 
      access_token_url='https://api.twitter.com/oauth/access_token', 
      base_url='https://api.twitter.com/1.1/' 
     ) 

    def authorize(self): 
     request_token = self.service.get_request_token(
      params={'oauth_callback': self.get_callback_url()} 
     ) 
     session['request_token'] = request_token 
     return redirect(self.service.get_authorize_url(request_token[0])) 

    def callback(self): 
     request_token = session.pop('request_token') 
     if 'oauth_verifier' not in request.args: 
      return None, None, None 
     oauth_session = self.service.get_auth_session(
      request_token[0], 
      request_token[1], 
      data={'oauth_verifier': request.args['oauth_verifier']} 
     ) 
     me = oauth_session.get('account/verify_credentials.json').json() 
     social_id = 'twitter$' + str(me.get('id')) 
     username = me.get('screen_name') 
     return social_id, username, None # Twitter does not provide email 

這是一個追蹤誤差

Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__ 
    return self.wsgi_app(environ, start_response) 
    File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app 
    response = self.make_response(self.handle_exception(e)) 
    File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception 
    reraise(exc_type, exc_value, tb) 
    File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app 
    response = self.full_dispatch_request() 
    File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request 
    rv = self.handle_user_exception(e) 
    File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception 
    reraise(exc_type, exc_value, tb) 
    File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request 
    rv = self.dispatch_request() 
    File "/usr/local/lib/python2.7/site-packages/flask_debugtoolbar/__init__.py", line 125, in dispatch_request 
    return view_func(**req.view_args) 
    File "/Users/Ben/Desktop/flask_practise/project/user/views.py", line 81, in oauth_authorize 
    return oauth.authorize() 
    File "/Users/Ben/Desktop/flask_practise/oauth.py", line 86, in authorize 
    params={'oauth_callback': self.get_callback_url()} 
    File "/Users/Ben/Desktop/flask_practise/oauth.py", line 22, in get_callback_url 
    _external=True) 
    File "/usr/local/lib/python2.7/site-packages/flask/helpers.py", line 312, in url_for 
    return appctx.app.handle_url_build_error(error, endpoint, values) 
    File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1641, in handle_url_build_error 
    reraise(exc_type, exc_value, tb) 
    File "/usr/local/lib/python2.7/site-packages/flask/helpers.py", line 305, in url_for 
    force_external=external) 
    File "/usr/local/lib/python2.7/site-packages/werkzeug/routing.py", line 1616, in build 
    raise BuildError(endpoint, values, method) 
BuildError: ('oauth_callback', {'provider': 'twitter'}, None) 

SOULUTION ---- Woops!我覺得自己像個白癡。我一直在改變文件在一個錯誤的目錄。我所要做的只是在我的oauth.py文件中添加user_blueprint。現在它工作正常!

回答

1

因爲你使用的藍圖,在金賈的模板,你將需要調用端點這樣

url_for('user_blueprint.oauth_authorize', provider='twitter') 
+0

嘿。我添加了藍圖。現在它不會給我那個錯誤,但是當我點擊那個按鈕時它會返回同樣的錯誤。 – Benji

+0

http://127.0.0.1:5000/authorize/twitter在該URL。我會實際更新主線程。 – Benji