我尝试在登录页面中添加带有Twitter重定向的登录信息。这叫做login.html。
<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(&#39; /回调/&#39)
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。现在它工作正常!
答案 0 :(得分:1)
因为您正在使用蓝图,所以在您的Jinja模板中,您需要像这样调用端点
url_for('user_blueprint.oauth_authorize', provider='twitter')