如何在 Windows 上使用 .NET8 C# 为 Firebase 推送通知 V1 API 创建 OAuth 2 令牌?

问题描述 投票:0回答:1

以下 .NET8 控制台应用程序尝试使用 Firebase 的新 V1 API 发送推送。

我从 Firebase 控制台生成的 configuration.json 文件创建一个 Firebase JWT 不记名令牌,其中包含:

{
  "type": "service_account",
  "project_id": "myProject",
  "private_key_id": "my private key id",
  "private_key": "-----BEGIN PRIVATE KEY-----\n  DATA \n-----END PRIVATE KEY-----\n",
  "client_email": "firebase-adminsdk-XXXX.gserviceaccount.com",
  "client_id": "999999999999",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-xxxxxx.iam.gserviceaccount.com",
  "universe_domain": "googleapis.com"
}

尝试发送请求时失败。 它返回:

{
   "error": {
       "code": 401,
       "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
       "status": "UNAUTHENTICATED"
   }
}

我可以在 Visual Studio 中看到从 GetJwtToken 返回的令牌是一个有效的 JWT 令牌,距离过期还有一个小时。

我犯了什么明显的错误? 我是否误认为它需要 JWT 令牌?

是否有一个 Firebase 例程可以为我提供它似乎期望的“OUath 2 访问令牌”?

using Google.Apis.Auth.OAuth2;
using RestSharp;

class Program {
    static async Task Main(string[] args) {

        // Send notification
        await SendNotificationAsync();
    }


    public static async Task SendNotificationAsync() {

        const string kMyToken = "myToken";

        // Get JWT token
        var bearerToken = await GetJwtToken();

        // Create client
        var client = new RestClient("https://fcm.googleapis.com/v1");

        // Create request
        var request = new RestRequest("projects/myProject/messages:send", Method.Post);

        // Set auth header
        request.AddHeader("Authorization", "Bearer " + bearerToken);

        // Set content type
        request.AddHeader("Content-Type", "application/json");

        // Construct notification payload
        var payload = new {
            message = new {
                token = kMyToken,
                notification = new {
                    title = "Test Title",
                    subtitle = "Test Sub-title",
                    body = "Test body.",
                    content_available = true
                },
                data = new {
                    key_1 = "posJob",
                    key_2 = "Value for key_2"
                }
            }
        };

        // Add payload to request
        request.AddJsonBody(payload);
        
        // Send request
        var response = await client.ExecuteAsync(request);

    }

    public static async Task<string> GetJwtToken() {
        try {
            // Read credentials file
            var json = File.ReadAllText("credentials.json");

            // Parse JSON credentials
            var credentials = GoogleCredential.FromJson(json);

            var scopes = "https://www.googleapis.com/auth/firebase.messaging";
            var accessToken = await credentials.UnderlyingCredential.GetAccessTokenForRequestAsync(scopes);

            return accessToken;
        } catch (Exception ex) {
            Console.WriteLine($"Exception: {ex.Message}");
            return "";
        }
    }
}
c# firebase oauth-2.0 push-notification
1个回答
0
投票

HTTP v1 API 确实需要 OAuth 2.0 访问令牌而不是 jwt 访问令牌。您需要修改解决方案以获得正确类型的令牌。

根据文档

GetAccessTokenForRequestAsync(字符串,CancellationToken)

获取访问令牌以授权请求。 OAuth2 访问令牌 从TokenServerUrl获取到的会在下面两个中返回 案例:

  1. 如果此凭证具有关联的范围,但 UseJwtAccessWithScopes 是假的;如果此凭据与域范围委派一起使用,则 即,用户已设置;否则,将返回本地签名的 JWT。
  2. 签名的 JWT 将包含“范围”声明,其范围位于 Scopes 中 如果有的话,否则它将包含一个“aud”声明 authUri。如果可能的话,使用缓存的令牌,并且该令牌仅 快过期了就刷新。

您需要首先确定您的凭据范围,然后将其传递给 GetAccessTokenForRequestAsync 函数。

试试这个:

var credentials = GoogleCredential.FromJson(json).CreateScoped("https://www.googleapis.com/auth/firebase.messaging");
var accessToken = await credentials.UnderlyingCredential.GetAccessTokenForRequestAsync();

而不是这个:

var credentials = GoogleCredential.FromJson(json);
    
var scopes = "https://www.googleapis.com/auth/firebase.messaging";
var accessToken = await credentials.UnderlyingCredential.GetAccessTokenForRequestAsync(scopes);
© www.soinside.com 2019 - 2024. All rights reserved.