如何使用 Firebase REST API(Python) 进行用户身份验证?

How to use Firebase REST API(Python) for authentication of a user?

我正在使用 Firebase 作为我的物联网应用程序的后端。在我的 Raspberry Pi 上使用 python,我将数据存储在 Firebase 上。目前我的数据库是 public for r/w。我使用 Console>Auth>Users 创建了一个虚拟帐户。我想使用此帐户通过我的 Raspberry Pi 使用 Python 和 REST 或任何 lib 登录我的 Firebase 应用程序。

登录后,我将使用 "Database>Rule" 限制用户仅 r/w 他的数据。我是 Firebase 的新手! Firebase 也弃用了旧文档。我想知道如何继续我的应用程序。我无法在 Python 或 REST API.

上找到有关如何执行此操作的任何信息

https://firebase.google.com/docs/auth/ 这是我找到的用于身份验证的新文档,其中不包含使用 REST 的信息 API。

有什么办法可以实现我的愿望吗?感谢任何帮助。

来自 Firebase Auth 团队的 Alfonso。

我们目前没有支持或记录的 REST API 身份验证。

您仍然可以通过旧版控制台创建项目并使用旧文档来了解如何创建您自己的自定义身份验证令牌,并将它们发送到数据库 REST API 以进行身份​​验证。

我最近 运行 遇到了这个问题,出于我的目的,我最终为 firebase_admin 制作了一个猴子补丁,它向主库添加了一个 verify_user 方法。 (我也放到pypi上了,https://pypi.org/project/firebase_fave/pip install firebase_fave

# import several different ways to make the code read like it would as part of the package it belongs in
import firebase_admin
from firebase_admin._user_mgt import *
from firebase_admin.auth import _get_auth_service, AuthError
from firebase_admin import firestore


# helper to add methods
def _add_method(cls):
    def cls_decorator(func):
        @wraps(func)
        def copied(self, *args, **kwargs): # wrap so we don't bind the func
            return func(self, *args, **kwargs)
        setattr(cls, func.__name__, copied)
        return func
    return cls_decorator


# add password verify to user manager
@_add_method(firebase_admin._user_mgt.UserManager)
def verify_user(self, **kwargs):
    """Gets the user data corresponding to the provided data and verifies"""
    key, key_type = self.get_user(**kwargs)['email'], 'email'

    if 'password' in kwargs:
        password = kwargs.pop('password')
    else:
        password = ''

    payload = {key_type:key, 'password':password, "returnSecureToken": True}

    try:
        response = self._client.request('post', 'verifyPassword', json=payload)
    except requests.exceptions.RequestException as error:
        msg = 'Failed to get user by {0}: {1}.'.format(key_type, key)
        self._handle_http_error(INTERNAL_ERROR, msg, error)
    else:
        if not response:
            raise ApiCallError(
                USER_NOT_FOUND_ERROR,
                'No user record found for the provided {0}: {1}.'.format(key_type, key))
        return response


# as in firebase_admin, we want a convenience method as well
def _outer_verify_user(password, **kwargs):
    """Verifies a user given password and one of uid or email.
    Args:
        uid: A user ID string.
        email: user e-mail address.
        app: An App instance (optional).

    Returns:
        UserRecord: A UserRecord instance.

    Raises:
        ValueError: if both user ID and email are None, empty, or malformed
        AuthError: If an error occurs while deleting the user account.
    """
    app = kwargs.pop('app', None)
    user_manager = _get_auth_service(app).user_manager
    kwargs['password'] = password
    try:
        return user_manager.verify_user(**kwargs)
    except firebase_admin._user_mgt.ApiCallError as error:
        raise AuthError(error.code, str(error), error.detail)


# finally, apply this convenience method to the class.
firebase_admin.verify_user = _outer_verify_user

您可以像这样使用来自 Python 的 REST API 连接到 Firebase。

假设您有用户的电子邮件和密码,您可以按如下方式进行身份验证:

url = 'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=' + API_KEY
headers = {"Content-Type": "application/json"}
data = '{"email":"' + email+ '","password":"' + password + '","returnSecureToken":true}'
response = requests.post(url, data=data, headers=headers)

这会给你一个授权令牌(除其他外):

rjson = response.json()
idToken = rjson['idToken']

然后您可以在进一步的 API 调用中使用,例如列出 Firestore 集合中的文档(替换 {projectID} 和 {collectionName}):

headers = {"Authorization": "Bearer " + idToken}   
url = 'https://firestore.googleapis.com/v1/projects/{projectID}/databases/(default)/documents/{collectionName}'    
response = requests.get(url, headers=headers)

然后可以使用您的数据访问规则来控制访问,并且用户没有像 Admin SDK 这样可怕的访问级别

Google 文档解释了如何使用 REST API here

获取令牌

以及一般如何使用RESTAPIhere