将 REST API 用于 id 令牌时对 Firebase 存储进行身份验证

Posted

技术标签:

【中文标题】将 REST API 用于 id 令牌时对 Firebase 存储进行身份验证【英文标题】:Authentication for Firebase Storage when using REST API for id token 【发布时间】:2019-04-30 15:23:43 【问题描述】:

我目前正在编写一个使用 firebase 身份验证的应用程序,但不是通过 firebase auth SDK,而是通过以下代码:

void submitlogin() async 
    if (_formKey.currentState.validate()) 
      _formKey.currentState.save();
      final Map<String, dynamic> successinfo = await postdata();
      if (successinfo['success']) 
        Navigator.pushReplacement(context,
            MaterialPageRoute(builder: (BuildContext context) => BMTHome()));
       else
        showDialog(
            context: context,
            builder: (BuildContext context) 
              return AlertDialog(
                title: Text('An error occurred!'),
                content: Text(successinfo['message']),
                actions: <Widget>[
                  FlatButton(
                      child: Text('OK'),
                      onPressed: () 
                        Navigator.of(context).pop();
                      )
                ],
              );
            );
    
  

  Future<Map> fetchData() async 
    final apiresponse = await http.get(
        'https://xxx.firebaseio.com/Users/$authUser.id.json?auth=$authUser.token');
    //print(apiresponse.body);
    return json.decode(apiresponse.body);
  

  Future<Map<String, dynamic>> postdata() async 
    final Map<String, dynamic> userdata = 
      'email': authenticateduser.email,
      'password': authenticateduser.password,
      'returnSecureToken': true
    ;
    final http.Response response = await http.post(
        'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=xxx',
        headers: "Accept": "application/json",
        body: json.encode(userdata));
    //print(json.decode(response.body));
    bool hasError = true;
    final Map<String, dynamic> responseData = json.decode(response.body);

    if (responseData.containsKey('idToken')) 
      hasError = false;
      message = 'Auth Succeeded';
      authUser = AuthUser(
          id: responseData['localId'],
          email: authenticateduser.email,
          token: responseData['idToken']);
     else if (responseData['error']['message'] == 'EMAIL_NOT_FOUND') 
      hasError = true;
      message =
          'No account exists for this email address, please create an account';
          setState(() 
      isLoading = false;
    );
     else if (responseData['error']['message'] == 'INVALID_PASSWORD') 
      hasError = true;
      message = 'Your password was incorrect';
      setState(() 
      isLoading = false;
    );
    
    setState(() 

    );
    print(authUser.id);
    return 'success': !hasError, 'message': message;
  

我通过将 authid 添加到实时数据库 REST API 的 URL 请求的末尾来使用 firebase 实时数据库。

我遇到的问题是我还想访问应用程序中的 firebase 存储,并且在不使用 firebase auth SDK 的情况下找不到使用 authid 访问存储的方法。目前您必须使用 Google 登录才能使用 SDK,这并没有提供我需要的帐户信息,因此我这样做了。

无论如何我可以保护我在 firebase 上的存储并且仍然将令牌传递给 firebase 存储以便能够访问它?

将数据发布到实时数据库的请求类型示例如下:

final http.Response response = await http.patch(
          'https://xxx.firebaseio.com/Users/$authUser.id.json?auth=$authUser.token',
          body: json.encode(userdatapostCode));

目前我上传图片的代码如下,但是如果我保护它,我似乎无法访问存储,并且我找不到传递authUser.token的方法

pickercam() async 
    print('callpicker');
    File img = await ImagePicker.pickImage(source: ImageSource.camera);
    image = img;
    final String uuid = Uuid().v1();
    StorageReference reference = _storage.ref().child(uuid);
    StorageUploadTask uploadTask = reference.putFile(image);
    var dowurl = await (await uploadTask.onComplete).ref.getDownloadURL();
    print(dowurl);
    final http.Response response = await http.patch(
        'https://xxx.firebaseio.com/Users/$authUser.id.json?auth=$authUser.token',
        headers: "Accept": "application/json",
        body: json.encode("profileurl": dowurl));
    profileurl = dowurl;
    setState(() );
    print('response');
  

提前致谢

【问题讨论】:

【参考方案1】:

为了做到这一点,我不得不转移到使用 sdk 的 firebase 身份验证和使用 google 登录的 firebase auth dart 包。

【讨论】:

以上是关于将 REST API 用于 id 令牌时对 Firebase 存储进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

REST API 令牌认证

Python 中的 Rest API - 获取身份验证令牌,然后将其设置为用于 POST 的变量

Django REST 框架:令牌身份验证不适用于生产

检查散列的 REST API 令牌

我应该将 id 令牌从我的 SPA 发送到我的 rest 后端吗?

使用访问令牌时,salesforce rest api 无效会话 id 错误