Firebase存储:使用http url路径和自定义访问令牌下载受访问保护的映像

时间:2016-12-04 13:12:47

标签: firebase firebase-authentication firebase-storage

我在通过网址和自定义访问令牌下载受访问保护的图片时遇到问题。

身份验证错误:

#include <iostream>
using namespace std;

int main() {
    while (cin.get() != 'x') {
        cout << "I am running." << endl;
    }
    return 0;
}

我错过了一些配置吗?

Http url我用来访问具有自定义标记作为查询参数的图像:

{
   "error": {
      "code": 403,
      "message": "Permission denied. Could not perform this operation"
   }
}

我的存储规则:

https://myfirebasestorage.googleapis.com/v0/b/myfirebasestorage-my_proj_id.appspot.com/o/images%2FIMG_4138.JPG?alt=media&token=TOKEN_GOT_USING_CREATE_CUSTOM_TOKEN_SIGN_IN

自定义令牌在java应用程序中生成,如下所示:

service firebase.storage {
  match /b/myfirebasestorage-my_proj_id.appspot.com/o {
    match /{allPaths=**} {
      allow read: if request.auth != null; 
    }
  }
}

我可以使用FirebaseAuth.getInstance()验证java应用程序中相同令牌的真实性.verifyIdToken(idToken)和日志输出如下:

  public static String createCustomToken(String userId, Map<String, Object> additionalClaims) {
    FirebaseOptions options = new FirebaseOptions.Builder()
        .setServiceAccount(new FileInputStream(FIREBASE_ACCESS_FILE)).build();
    FirebaseApp.initializeApp(options);

    Task<String> customToken = FirebaseAuth.getInstance().createCustomToken(userId, additionalClaims);
    return customToken.getResult().toString();
  }

从Web客户端代码登录此自定义令牌后,我可以看到正确的响应,如下所示

    VerifiedToken=>uid: user_id_1,
email: bhaarat@new.mail,
additionalClaims: {
  "aud": "myfirebasestorage-<my_proj_id>",
  "auth_time": 1480609782,
  "email": "bhaarat@new.mail",
  "email_verified": false,
  "exp": 1480621773,
  "iat": 1480618173,
  "iss": "https://securetoken.google.com/myfirebasestorage-my_proj_id",
  "sub": "user_id_1",
  "circleId": "circle_id_1",
  "memberId": "user_id_1",
  "user_id": "user_id_1",
  "firebase": {
    "identities": {

    },
    "sign_in_provider": "custom”
  }
}

注意:我可以使用与下面相同的自定义令牌访问firebase数据库中的节点。

{
  "uid": "user_id_1",
  "displayName": null,
  "photoURL": null,
  "email": null,
  "emailVerified": false,
  "isAnonymous": false,
  "providerData": [],
  "apiKey": "API_KEY",
  "appName": "[DEFAULT]",
  "authDomain": "myfirebasestorage-<my_proj_id>.firebaseapp.com",
  "stsTokenManager": {
    "apiKey": "API_KEY",
    "refreshToken": "REFRESH_TOKEN_FROM_FIREBASE",
    "accessToken": "ACCESS_TOKEN_FROM_FIREBASE",
    "expirationTime": 1480621773681
  },
  "redirectEventId": null
}

我的数据库规则

https://myfirebasestorage-my_proj_id.firebaseio.com/games/basic_info.json?orderBy=%22owner_id%22&limitToFirst=30&auth=ACCESS_TOKEN_FROM_FIREBASE

2 个答案:

答案 0 :(得分:3)

简短的回答是?token=<UUID>使用的Storage?auth=<Firebase Auth JWT or Database Secret>使用的Realtime Database不同(因此它们的名称不同)。

存储提供了一种格式为https://myfirebasestorage.googleapis.com/v0/b/<BUCKET>/o/<OBJECT>?alt=media&token=<UNGUESSABLE_UUID>的无法获取的下载网址,该网址旨在与不使用Firebase身份验证的用户共享(想象与您的家人/朋友分享照片,但您不想制作这些照片下载一个应用程序来做到这一点。)

如果您希望下载受到存储安全规则的保护,则需要使用getBytes()getStreamgetFile()等原生Android方法。{{3} }。

答案 1 :(得分:0)

您可以尝试为所有请求设置规则

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write;
    }
  }
}