I am using authlib with a pretty standard OAuth2 flow.
import pickle
import json
import os.path
from requests.models import Response
from authlib.integrations.flask_client import OAuth, OAuthError
class BaseApi(object):
def __init__(self, oauth_client, config_directory, token_file=''):
self.oauth_client = oauth_client
if token_file:
self.token_file = token_file
else:
self.token_file = os.path.join(config_directory, 'token.pickle')
@property
def token(self):
try:
print ("Token: %s" % self.__token)
return self.__token
except AttributeError:
if os.path.exists(self.token_file):
with open(self.token_file, 'rb') as f:
self.__token = pickle.load(f)
print ("Pickled Token: %s" % self.token)
return self.__token
@token.setter
def token(self, new_token):
self.__token = new_token
# The authorizaiton flow sends us to the OAuth provider
# with a redirect back to our app
def login(self, state=None):
return self.oauth_client.authorize_redirect(self.auth_callback, state=state)
# Our authorized endpoint.
def authorized(self,request):
# Get the access token!
token = self.oauth_client.authorize_access_token(client_id=self.oauth_client.client_id,
client_secret=self.oauth_client.client_secret)
#if resp is None or resp.get('access_token') is None:
# return 'Access denied: error=%s resp=%s' % (
# request.args,
# resp
# )
self.token = token
This is all subclassed in a different module:
from __future__ import print_function
import json
from backend.oauth_base import BaseApi, OAuth, load_credentials_file
from urllib.parse import urlparse
from backend import app, url_for # This is the flask app
from flask import request, redirect, jsonify
import requests
import os
config_directory = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config')
class BasecampApi(BaseApi):
def __init__(self):
oauth = OAuth(app)
credentials = load_credentials_file(os.path.join(config_directory,
'credentials.json'))
oauth.register(
name='basecamp',
client_id=credentials['client_id'],
client_secret=credentials['client_secret'],
api_base_url='https://3.basecampapi.com/',
request_token_url=None,
request_token_params={'type': 'web_server'},
access_token_url='https://launchpad.37signals.com/authorization/token',
access_token_params={'type': 'web_server'},
authorize_url='https://launchpad.37signals.com/authorization/new',
authorize_params={'type': 'web_server'}
)
oauth_client = oauth.create_client('basecamp')
super().__init__(oauth_client, config_directory)
Everything here works, but I'm confused as to why I need to pass client_id and client_secret explicitly in the authorize access token.
token = self.oauth_client.authorize_access_token()
Causes the basecamp API to throw an error complaining about a lack of clien_id (and then client_secret).
This is different from the docs (which I admittedly found confusing). Is this the expected behavior?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…