如何在没有Firebase存储规则的情况下将Google云存储桶路径限制为特定用户?

bt1cpqcv  于 2023-03-19  发布在  Go
关注(0)|答案(1)|浏览(139)

我正在构建一个移动的应用程序,该应用程序要求我的Cloud Storage存储桶位于巴黎。因此,我无法使用Firebase Storage,因为该区域在巴黎不可用。
我已经设置了一个Python后端使用云函数上传/删除文件。
我的存储桶中的一个文件如下所示:https://storage.googleapis.com/my_bucket/644f1576-9e2f-486e-b33f-e326b6c596e/folder1/6fiz576-9e2f-486e-b33f-e3b6c5996e/folder2/8b205722-c132-4ca2-b104-6f357f58a679.jpg
uid 644f1576-9e2f-486e-b33f-e326b6c596e就像一个组,我需要授予访问下面所有文件的权限,只有属于我的后端中的该组的用户。
如果这是不可能的,我想至少防止任何未经授权的用户访问(使用Firebase认证作为登录方法)。
使用Firebase存储规则,我想这是可能的,但由于我不能使用它们,我真的不知道我应该如何继续这里...我不是很有信心添加一个服务帐户文件在我的移动的应用程序客户端代码。
现在我所有的文件都是公开的,我至少需要限制访问我的应用程序的(认证)用户。而且现在,如果我粘贴在我的浏览器的URL是可读的,我不能允许。
先谢了
编辑:我已经浏览了documentation,它虽然有帮助,但没有回答常见的用例。
它提供了设置权限的工具,但没有“如何使用Firebase认证到云存储桶”的示例。
编辑2:
下面是我的cloud函数中的python代码示例:

@functions_framework.http
def users(event):
    method = event.method
    endpoint = event.path
    headers = event.headers
    route_key = method + " " + endpoint
    logging.info(f"Route key : {route_key}")
    user_auth_id = ""
    if "Authorization" in headers:
        user_auth_id = check_token(headers["Authorization"])
    if user_auth_id == "":
        return {"error": "not allowed"}
    if route_key == "POST /upload":
        file = event.files
        body = event.form
        return upload_file(user_auth_id, file, body)
    return {"error": "not allowed"}

def check_token(token):
    try:
        decoded_token = auth.verify_id_token(token)
        logging.info(f"verified token : {decoded_token}")
        if "disabled" in decoded_token and decoded_token["disabled"]:
            return "disabled"
        if "uid" in decoded_token:
            return decoded_token["uid"]
        return ""
    except Exception as e:
        logging.error(f"check_token : {e}")
        return ""

def upload_file(user_auth_id, files, payload):
    try:
        photo = files["url"] if "url" in files else ""
        logging.info(f"Payload upload : {payload}")
        uid = payload["uid"]
        if photo != "":
            name = str(uuid.uuid4()) + ".jpg"
            bucket_name = os.environ.get("BUCKET_NAME")
            bucket = storage_client.get_bucket(bucket_name)
            delete_files(user_auth_id, profile_photo=True, bucket=bucket)
            blob = bucket.blob(f"documents/{uid}/users/" + user_auth_id + "/profile/" + name)
            logging.info(f"Blob : {blob.path}")
            blob.upload_from_string(photo.read())
            blob.make_public()
            return blob.public_url
        return ""
    except Exception as e:
        logging.error(f"upload_file: {e}")
        return ""

def delete_files(user_auth_id, uid, profile_photo=False, bucket=None):
    try:
        if not bucket:
            bucket_name = os.environ.get("BUCKET_NAME")
            bucket = storage_client.get_bucket(bucket_name)
        path = "/profile" if profile_photo else ""
        blobs = bucket.list_blobs(prefix=f'documents/{uid}/users/' + user_auth_id + path)
        for blob in blobs:
            blob.delete()
    except Exception as e:
        logging.error(f"delete_files: {e}")
        return {"error": "internal"}

upload_file方法返回我存储在DB中的公共URL,然后我的客户端可以“读取”此URL,但如果可能,我希望限制对此URL的访问,而不使用添加后端代码(如果可能,仅使用云存储规则?)

w46czmvw

w46czmvw1#

本人理解:
1.用户在移动的应用上通过Firebase Authentication服务进行身份验证,因此用户拥有Firebase ID令牌,这是一个签名的JWT,用于在Firebase项目中安全地标识用户。
1.用户使用图像调用Python基础后端,后端将其上传到位于巴黎的bucket
如果上述假设是正确的,您可以执行以下操作:

  • 当应用调用Python后端时,传递Firebase ID令牌,然后在后端使用Firebase Admin SDK验证该ID令牌,如这里所述。
  • 根据用户的uid检查该用户是否属于所需的组(我不知道您是如何设置基于组的访问策略的,可能是通过Custom Claims还是通过Firestore documents?)并相应地授予(或不授予)访问权限。

删除的机制是一样的,当调用你的Python基础后端时,你只需要传递文件的URL而不是传递一个文件。

相关问题