使用 LWP::Authen::OAuth2 访问受 OAuth2 保护的 Google API 时出现问题
Problem accessing Google API protected with OAuth2 by using LWP::Authen::OAuth2
我目前正在 perl 服务器上编写服务,该服务应向 Firebase 云消息传递 API 发送请求,然后将推送通知发送到应用程序实例。
由于 FCM 是 Google API 系列的一部分,因此需要 OAuth2 令牌才能访问 API。在我的研究过程中,我发现 this perl solution. Because my service is running on an non-Google server environment, I can't use Google Application Default Credentials, but have to provide them manually, so I downloaded a json containing a private key following this 描述。
阅读 documentation of LWP::Authen::OAuth2 我有点困惑,在哪里将 json 中的哪个参数放入 $oauth2
对象中,因为经常使用不同的名称来引用相同的对象价值观,就像我怀疑的那样。
与我的 firebase 项目相关的json:
{
"type": "service_account",
"project_id": "my_project_id",
"private_key_id": "some_key_id",
"private_key": "-----BEGIN PRIVATE KEY-----very_long_key-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-o8sf4@<my_project_id>.iam.gserviceaccount.com",
"client_id": "some_client_id",
"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-o8sf4%40<my_project_id>.iam.gserviceaccount.com"
}
$oauth
对象的实现如下所示:
my $oauth2 = LWP::Authen::OAuth2->new(
client_id => "Public from service provider",
#probably that will be "some_client_id" from above
client_secret => "s3cr3t fr0m svc prov",
#the "very_long_key"?
service_provider => "Google",
#the "auth_uri"? That's what I would suggest here
#I've read some about the LWP::Authen::OAuth2::ServiceProvider module
#do I have to create an instance of that here?
#if so, which params do I need for that from the json?
redirect_uri => "https://your.url.com/",
#the FCM api I want to call?
# Optional hook, but recommended.
save_tokens => \&save_tokens,
save_tokens_args => [ $dbh ],
# This is for when you have tokens from last time.
token_string => $token_string.
#yes, i copy-pasted that from the docs
);
现在,作为 Perl 的初学者并且不喜欢模棱两可的键值名称,我有点困惑,应该把哪个值放在哪里,如果有人能在这里帮助我提供指导,我会很高兴,要做什么放在哪里,即使这看起来是非常菜鸟的问题,对我来说也很重要:D。所以我感谢每一个有用的答案!
编辑
当尝试使用 Crypt::JWT 在我的 perl 服务中手动生成 JSON Web 令牌 时,我遇到了另一条绊线,这让我怀疑来自 Google "https://www.googleapis.com/auth/firebase.messaging"
的相应身份验证 API 仍然接受 Bearer 令牌...我尝试生成我的 JWT,这似乎是成功的,但是我发送给实际 FCM 的请求 API 然后给了我这个:
Request had invalid authentication credentials.
Expected OAuth 2 access token, login cookie
or other valid authentication credential
在打印为 String 的响应中,我发现了这个小家伙,这让我很困惑:
Client-Warning: Unsupported authentication scheme 'bearer'
现在我非常不确定,FCM API 仍然支持不记名令牌,即使它们在引用 docs page 的示例中使用。有没有人有关于那个的最新信息?非常感谢!
深入研究各种文档并测试一些我意识到的东西,LWP::Authen::OAuth2 不仅是一点点开销,对于创建一个非常小的 HTTPS 请求到 OAuth2 保护 API,它是目前也不可能。
警告隐藏在托管身份验证 API 的 service_provider
中,我必须调用它来验证和授权我的服务以访问实际的 Firecase 云消息传递 API .在我的例子中,这是 Google,更准确地说是 https://www.googleapis.com/auth/firebase.messaging
,在代码中也称为 scope
。
现在一个服务提供商可以为不同的客户提供不同的身份验证API。这就是为什么一些服务提供商需要一个额外的参数——分别是 client_type
或 type
(为了明确起见,我将使用 client_type
)——这也会影响通过 OAuth2 的身份验证和授权过程。
当创建一个新的 $oauth2
对象,并为字段 service_provider
赋值时,模块 LWP::Authen::OAuth2::ServiceProvider 的对象被创建,可能还需要它的参数,比如scope
,用于定义您希望获得授权的 API 家庭,并根据该 client_type
.
现在 Google 不是无名服务提供者,因此已经有一个预构建的 ServiceProvider 模块,明确地为 Google APIs : LWP::Authen::OAuth2::ServiceProvider::Google. This automatically fills in some parameters of a ServiceProvider object, and holds a hash of available client_types
to make sure you use one of them, because depending on the client_type
a specific sub-module of ServiceProvider::Google 被创建内部。
所以我尝试这样测试:
my $oauth2 = LWP::Authen::OAuth2->new(
service_provider => "Google",
scope => "https://www.googleapis.com/auth/firebase.messaging",
client_type => "service_account", #referring to 'type' in the json
client_id => "Public from service provider",
client_secret => "s3cr3t fr0m svc prov",
redirect_uri => "this-server.mydomain.com"
);
根据进一步的描述 here and sending a request with the built-in LWP::UserAgent object I still got an 401 error UNAUTHENTICATED
which confused me a lot. So when I read the documentation the I-don't-know-what time I stepped across this tiny line in the client_types
chapter of ServiceProvider::Google:
Service Account
This client_type is for applications that login to the developer's account using the developer's credentials. See https://developers.google.com/accounts/docs/OAuth2ServiceAccount for Google's documentation.
This is not yet supported, and would require the use of JSON Web Tokens to support.
是的,这有点让整个 LWP:Authen::OAuth 家族无法访问 Firebase API,因为几乎所有人都有 client_type => "service_account"
。现在我的项目有一个截止日期,我等不及模块得到扩展,否则我自己扩展它会超出我的 perl 技能。
但在绝望的泪水之间总有一线希望,因为我发现 this Google docs page with a live-saving addendum, that it's possible to use a JSON Web Token as a Bearer token. Researching for that I found more than one Perl solution to generate JWT from JSONs like a service account, and also this 非常有用的 Whosebug 答案为我指明了走出瓶颈的出路。
我目前正在 perl 服务器上编写服务,该服务应向 Firebase 云消息传递 API 发送请求,然后将推送通知发送到应用程序实例。
由于 FCM 是 Google API 系列的一部分,因此需要 OAuth2 令牌才能访问 API。在我的研究过程中,我发现 this perl solution. Because my service is running on an non-Google server environment, I can't use Google Application Default Credentials, but have to provide them manually, so I downloaded a json containing a private key following this 描述。
阅读 documentation of LWP::Authen::OAuth2 我有点困惑,在哪里将 json 中的哪个参数放入 $oauth2
对象中,因为经常使用不同的名称来引用相同的对象价值观,就像我怀疑的那样。
与我的 firebase 项目相关的json:
{
"type": "service_account",
"project_id": "my_project_id",
"private_key_id": "some_key_id",
"private_key": "-----BEGIN PRIVATE KEY-----very_long_key-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-o8sf4@<my_project_id>.iam.gserviceaccount.com",
"client_id": "some_client_id",
"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-o8sf4%40<my_project_id>.iam.gserviceaccount.com"
}
$oauth
对象的实现如下所示:
my $oauth2 = LWP::Authen::OAuth2->new(
client_id => "Public from service provider",
#probably that will be "some_client_id" from above
client_secret => "s3cr3t fr0m svc prov",
#the "very_long_key"?
service_provider => "Google",
#the "auth_uri"? That's what I would suggest here
#I've read some about the LWP::Authen::OAuth2::ServiceProvider module
#do I have to create an instance of that here?
#if so, which params do I need for that from the json?
redirect_uri => "https://your.url.com/",
#the FCM api I want to call?
# Optional hook, but recommended.
save_tokens => \&save_tokens,
save_tokens_args => [ $dbh ],
# This is for when you have tokens from last time.
token_string => $token_string.
#yes, i copy-pasted that from the docs
);
现在,作为 Perl 的初学者并且不喜欢模棱两可的键值名称,我有点困惑,应该把哪个值放在哪里,如果有人能在这里帮助我提供指导,我会很高兴,要做什么放在哪里,即使这看起来是非常菜鸟的问题,对我来说也很重要:D。所以我感谢每一个有用的答案!
编辑
当尝试使用 Crypt::JWT 在我的 perl 服务中手动生成 JSON Web 令牌 时,我遇到了另一条绊线,这让我怀疑来自 Google "https://www.googleapis.com/auth/firebase.messaging"
的相应身份验证 API 仍然接受 Bearer 令牌...我尝试生成我的 JWT,这似乎是成功的,但是我发送给实际 FCM 的请求 API 然后给了我这个:
Request had invalid authentication credentials.
Expected OAuth 2 access token, login cookie
or other valid authentication credential
在打印为 String 的响应中,我发现了这个小家伙,这让我很困惑:
Client-Warning: Unsupported authentication scheme 'bearer'
现在我非常不确定,FCM API 仍然支持不记名令牌,即使它们在引用 docs page 的示例中使用。有没有人有关于那个的最新信息?非常感谢!
深入研究各种文档并测试一些我意识到的东西,LWP::Authen::OAuth2 不仅是一点点开销,对于创建一个非常小的 HTTPS 请求到 OAuth2 保护 API,它是目前也不可能。
警告隐藏在托管身份验证 API 的 service_provider
中,我必须调用它来验证和授权我的服务以访问实际的 Firecase 云消息传递 API .在我的例子中,这是 Google,更准确地说是 https://www.googleapis.com/auth/firebase.messaging
,在代码中也称为 scope
。
现在一个服务提供商可以为不同的客户提供不同的身份验证API。这就是为什么一些服务提供商需要一个额外的参数——分别是 client_type
或 type
(为了明确起见,我将使用 client_type
)——这也会影响通过 OAuth2 的身份验证和授权过程。
当创建一个新的 $oauth2
对象,并为字段 service_provider
赋值时,模块 LWP::Authen::OAuth2::ServiceProvider 的对象被创建,可能还需要它的参数,比如scope
,用于定义您希望获得授权的 API 家庭,并根据该 client_type
.
现在 Google 不是无名服务提供者,因此已经有一个预构建的 ServiceProvider 模块,明确地为 Google APIs : LWP::Authen::OAuth2::ServiceProvider::Google. This automatically fills in some parameters of a ServiceProvider object, and holds a hash of available client_types
to make sure you use one of them, because depending on the client_type
a specific sub-module of ServiceProvider::Google 被创建内部。
所以我尝试这样测试:
my $oauth2 = LWP::Authen::OAuth2->new(
service_provider => "Google",
scope => "https://www.googleapis.com/auth/firebase.messaging",
client_type => "service_account", #referring to 'type' in the json
client_id => "Public from service provider",
client_secret => "s3cr3t fr0m svc prov",
redirect_uri => "this-server.mydomain.com"
);
根据进一步的描述 here and sending a request with the built-in LWP::UserAgent object I still got an 401 error UNAUTHENTICATED
which confused me a lot. So when I read the documentation the I-don't-know-what time I stepped across this tiny line in the client_types
chapter of ServiceProvider::Google:
Service Account
This client_type is for applications that login to the developer's account using the developer's credentials. See https://developers.google.com/accounts/docs/OAuth2ServiceAccount for Google's documentation.
This is not yet supported, and would require the use of JSON Web Tokens to support.
是的,这有点让整个 LWP:Authen::OAuth 家族无法访问 Firebase API,因为几乎所有人都有 client_type => "service_account"
。现在我的项目有一个截止日期,我等不及模块得到扩展,否则我自己扩展它会超出我的 perl 技能。
但在绝望的泪水之间总有一线希望,因为我发现 this Google docs page with a live-saving addendum, that it's possible to use a JSON Web Token as a Bearer token. Researching for that I found more than one Perl solution to generate JWT from JSONs like a service account, and also this 非常有用的 Whosebug 答案为我指明了走出瓶颈的出路。