【问题标题】:Firebase DB HTTP API Auth: When and how to refresh JWT token?Firebase DB HTTP API Auth:何时以及如何刷新 JWT 令牌?
【发布时间】:2016-12-02 12:44:57
【问题描述】:

我正在尝试使用 HTTP API 将 Python webapp 写入 Firebase DB(我正在使用 Google I/O 2016 上展示的新版 Firebase)。

到目前为止,我的理解是,我想要完成的特定类型的写入是通过对这种类型的 URL 的 POST 请求进行的:

https://my-project-id.firebaseio.com/{path-to-resource}.json

我缺少的是 auth 部分:如果我正确理解了它,JWT 应该作为 Authorization : Bearer {token} 在 HTTP Authorization 标头中传递。

所以我创建了一个服务帐户,下载了它的私钥并使用它来生成 JWT,将其添加到请求标头中,并且请求成功写入 Firebase DB。

现在 JWT 已过期,任何对 firebase 数据库的类似请求都失败了。

当然我应该生成一个新令牌,但问题是:我没想到自己会处理令牌生成和刷新,我习惯的大多数 HTTP API 只需要在请求中传递一个静态 api 密钥,所以只需将 stati api 密钥字符串添加到请求中,我的 webapps 就可以保持相对简单。

如果我必须处理令牌的生成和过期,则 webapp 逻辑需要变得更加复杂(因为我必须存储令牌,检查它是否仍然有效并在没有时生成一个新的),或者我可以为每个请求生成一个新令牌(但这真的有意义吗?)。

我想知道在这方面是否有最佳做法可以遵循,或者我是否在有关此主题的文档中遗漏了某些内容。

谢谢, 马可


附录

这是我当前正在运行的代码:

import requests
import json
from oauth2client.service_account import ServiceAccountCredentials

_BASE_URL = 'https://my-app-id.firebaseio.com'
_SCOPES = [
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/firebase.database'
]

def _get_credentials():
    credentials = ServiceAccountCredentials.from_json_keyfile_name('my_service_account_key.json', scopes=_SCOPES)
    return credentials.get_access_token().access_token

def post_object():
    url = _BASE_URL + '/path/to/write/to.json'

    headers = {
        'Authorization': 'Bearer '+ _get_credentials(),
        'Content-Type': 'application/json'
    }

    payload = {
                'title': title,
                'message': alert
              }

    return requests.post(url,
                         data=json.dumps(payload),
                         headers=headers)

目前,每个请求都会生成一个新的 JWT。这对我来说似乎不是最佳选择。是否可以生成一个不会过期的令牌?

【问题讨论】:

  • 大概这是为了服务器端访问吧?您实际上最想做的是使用从服务帐户生成的 Google 访问令牌。 Here's an example 如何在 Ruby 中做到这一点。
  • 是的,它用于服务器端访问。我最终所做的已添加到问题文本中。虽然我仍然觉得它不是最优的,因为我每次请求都会生成一个新的 JWT。对于服务器端访问,我希望可以使用静态(不会过期)令牌。
  • 出于安全原因,从 3.x SDK 开始,我们不再允许使用单个长寿命不记名令牌。
  • 我也遇到了令牌在一小时后过期的问题。 @MichaelBleigh是通过在每个API请求之前刷新令牌来不遇到令牌过期消息的唯一方法吗?还是有更好的方法来做到这一点?谢谢!
  • 有关于这个话题的消息吗?

标签: python firebase firebase-authentication


【解决方案1】:

感谢代码示例。通过使用为 http 创建一个经过身份验证的包装器的 credentials.authorize 函数,我让它工作得更好。

from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
import json

_BASE_URL = 'https://my-app-id.firebaseio.com'
_SCOPES = [
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/firebase.database'
] 

# Get the credentials to make an authorized call to firebase    
credentials = ServiceAccountCredentials.from_json_keyfile_name(
    _KEY_FILE_PATH, scopes=_SCOPES)

# Wrap the http in the credentials.  All subsequent calls are authenticated
http_auth = credentials.authorize(Http())

def post_object(path, objectToSave):
  url = _BASE_URL + path

  resp, content = http_auth.request(
      uri=url,
      method='POST',
      headers={'Content-Type': 'application/json'},
      body=json.dumps(objectToSave),
  )

  return content

objectToPost = {
  'title': "title",
  'message': "alert"
}

print post_object('/path/to/write/to.json', objectToPost)

【讨论】:

    猜你喜欢
    • 2020-12-05
    • 2018-03-04
    • 2016-10-08
    • 2015-06-28
    • 2021-07-10
    • 2018-10-21
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多