在 Google App Engine 上使用 flask_client 自动或手动刷新访问令牌
Automatically or manually refreshing access token with flask_client on Google App Engine
我能够成功地使用第 3 方 OAuth2 提供商 (Xero) 授权我的应用程序,但无法自动或手动刷新令牌。
文档建议 authlib 可以自动执行此操作。我从 Authlib 文档中尝试了两种不同的方法,在 flask client docs they give an example of "Auto Update Token via Signal", and on the web client docs 他们注册了一个 "update_token" 函数。
无论使用哪种方法,都不会尝试刷新令牌,请求会使用过期令牌传递给 Xero,我收到错误消息,继续的唯一方法是手动重新授权应用程序与 Xero.
以下是网络客户端文档中 "update_token" 方法的相关代码:
#this never ends up getting called.
def save_xero_token(name,token,refresh_token=None,access_token=None,tenant_id=None):
logging.info('Called save xero token.')
#removed irrelevant code that stores token in NDB here.
cache = Cache()
oauth = OAuth(app,cache=cache)
oauth.register(name='xero',
client_id = Meta.xero_consumer_client_id,
client_secret = Meta.xero_consumer_secret,
access_token_url = 'https://identity.xero.com/connect/token',
authorize_url = 'https://login.xero.com/identity/connect/authorize',
fetch_token = fetch_xero_token,
update_token = save_xero_token,
client_kwargs={'scope':' '.join(Meta.xero_oauth_scopes)},
)
xero_tenant_id = 'abcd-123-placeholder-for-Whosebug'
url = 'https://api.xero.com/api.xro/2.0/Invoices/ABCD-123-PLACEHOLDER-FOR-Whosebug'
headers = {'Xero-tenant-id':xero_tenant_id,'Accept':'application/json'}
response = oauth.xero.get(url,headers=headers) #works fine until token is expired.
我将我的令牌存储在以下 NDB 模型中:
class OAuth2Token(ndb.Model):
name = ndb.StringProperty()
token_type = ndb.StringProperty()
access_token = ndb.StringProperty()
refresh_token = ndb.StringProperty()
expires_at = ndb.IntegerProperty()
xero_tenant_id = ndb.StringProperty()
def to_token(self):
return dict(
access_token=self.access_token,
token_type=self.token_type,
refresh_token=self.refresh_token,
expires_at=self.expires_at
)
为了完整起见,以下是我如何存储来自 Xero 的初始响应(效果很好):
@app.route('/XeroOAuthRedirect')
def xeroOAuthLanding():
token = oauth.xero.authorize_access_token()
connections_response = oauth.xero.get('https://api.xero.com/connections')
connections = connections_response.json()
for tenant in connections:
print('saving first org, this app currently supports one xero org only.')
save_xero_token('xero',token,tenant_id=tenant['tenantId'])
return 'Authorized application with Xero'
如果自动刷新失败,我如何才能使自动刷新工作,以及如何在使用 flask 客户端时手动触发刷新请求?
我相信我在这里发现了问题,其根源是在初始化 OAuth 时传递了缓存(用于临时凭证存储):
cache = Cache()
oauth = OAuth(app,cache=cache)
传递缓存时,它似乎抢占了 update_token(也可能是 fetch_token)参数。
应该很简单:
oauth = OAuth(app)
oauth.register(name='xero',
client_id = Meta.xero_consumer_client_id,
client_secret = Meta.xero_consumer_secret,
access_token_url = 'https://identity.xero.com/connect/token',
authorize_url = 'https://login.xero.com/identity/connect/authorize',
fetch_token = fetch_xero_token,
update_token = save_xero_token,
client_kwargs={'scope':' '.join(Meta.xero_oauth_scopes)},
)
此外,我的 "save_xero_token" 函数的参数需要调整以匹配文档,但这与问题所解决的原始问题无关。
我能够成功地使用第 3 方 OAuth2 提供商 (Xero) 授权我的应用程序,但无法自动或手动刷新令牌。
文档建议 authlib 可以自动执行此操作。我从 Authlib 文档中尝试了两种不同的方法,在 flask client docs they give an example of "Auto Update Token via Signal", and on the web client docs 他们注册了一个 "update_token" 函数。
无论使用哪种方法,都不会尝试刷新令牌,请求会使用过期令牌传递给 Xero,我收到错误消息,继续的唯一方法是手动重新授权应用程序与 Xero.
以下是网络客户端文档中 "update_token" 方法的相关代码:
#this never ends up getting called.
def save_xero_token(name,token,refresh_token=None,access_token=None,tenant_id=None):
logging.info('Called save xero token.')
#removed irrelevant code that stores token in NDB here.
cache = Cache()
oauth = OAuth(app,cache=cache)
oauth.register(name='xero',
client_id = Meta.xero_consumer_client_id,
client_secret = Meta.xero_consumer_secret,
access_token_url = 'https://identity.xero.com/connect/token',
authorize_url = 'https://login.xero.com/identity/connect/authorize',
fetch_token = fetch_xero_token,
update_token = save_xero_token,
client_kwargs={'scope':' '.join(Meta.xero_oauth_scopes)},
)
xero_tenant_id = 'abcd-123-placeholder-for-Whosebug'
url = 'https://api.xero.com/api.xro/2.0/Invoices/ABCD-123-PLACEHOLDER-FOR-Whosebug'
headers = {'Xero-tenant-id':xero_tenant_id,'Accept':'application/json'}
response = oauth.xero.get(url,headers=headers) #works fine until token is expired.
我将我的令牌存储在以下 NDB 模型中:
class OAuth2Token(ndb.Model):
name = ndb.StringProperty()
token_type = ndb.StringProperty()
access_token = ndb.StringProperty()
refresh_token = ndb.StringProperty()
expires_at = ndb.IntegerProperty()
xero_tenant_id = ndb.StringProperty()
def to_token(self):
return dict(
access_token=self.access_token,
token_type=self.token_type,
refresh_token=self.refresh_token,
expires_at=self.expires_at
)
为了完整起见,以下是我如何存储来自 Xero 的初始响应(效果很好):
@app.route('/XeroOAuthRedirect')
def xeroOAuthLanding():
token = oauth.xero.authorize_access_token()
connections_response = oauth.xero.get('https://api.xero.com/connections')
connections = connections_response.json()
for tenant in connections:
print('saving first org, this app currently supports one xero org only.')
save_xero_token('xero',token,tenant_id=tenant['tenantId'])
return 'Authorized application with Xero'
如果自动刷新失败,我如何才能使自动刷新工作,以及如何在使用 flask 客户端时手动触发刷新请求?
我相信我在这里发现了问题,其根源是在初始化 OAuth 时传递了缓存(用于临时凭证存储):
cache = Cache()
oauth = OAuth(app,cache=cache)
传递缓存时,它似乎抢占了 update_token(也可能是 fetch_token)参数。
应该很简单:
oauth = OAuth(app)
oauth.register(name='xero',
client_id = Meta.xero_consumer_client_id,
client_secret = Meta.xero_consumer_secret,
access_token_url = 'https://identity.xero.com/connect/token',
authorize_url = 'https://login.xero.com/identity/connect/authorize',
fetch_token = fetch_xero_token,
update_token = save_xero_token,
client_kwargs={'scope':' '.join(Meta.xero_oauth_scopes)},
)
此外,我的 "save_xero_token" 函数的参数需要调整以匹配文档,但这与问题所解决的原始问题无关。