【问题标题】:Automatically or manually refreshing access token with flask_client on Google App Engine在 Google App Engine 上使用 flask_client 自动或手动刷新访问令牌
【发布时间】:2020-07-26 10:02:05
【问题描述】:

我成功地使用第 3 方 OAuth2 提供者 (Xero) 授权我的应用程序,但无法自动或手动刷新令牌。

文档建议 authlib 可以自动执行此操作。我从 Authlib 文档中尝试了两种不同的方法,在 flask client docs 他们给出了“通过信号自动更新令牌”的示例,在 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-stackoverflow'
url = 'https://api.xero.com/api.xro/2.0/Invoices/ABCD-123-PLACEHOLDER-FOR-STACKOVERFLOW'
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客户端时手动触发刷新请求?

【问题讨论】:

    标签: python-3.x google-app-engine flask authlib


    【解决方案1】:

    我相信我在这里找到了问题,它的根源是在初始化 OAuth 时传递了一个 Cache(用于临时凭证存储):

    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”函数的参数需要调整以匹配文档,但这与问题所解决的原始问题无关。

    【讨论】:

      猜你喜欢
      • 2014-07-30
      • 2021-02-22
      • 2021-09-23
      • 2019-06-29
      • 2016-08-21
      • 2015-10-05
      • 1970-01-01
      • 1970-01-01
      • 2020-04-05
      相关资源
      最近更新 更多