クライアント側でGoogleサインインプロセスを正常に実行できるPHP / JavaScriptを使用したWebページがあります。次に、取得したトークンをバックエンドに転送します。バックエンドは、Spring-Socialを使用してソーシャル接続を作成し、アプリが承認されているAPIを呼び出すことができるようにします。Facebook(OAUTH2)とTwitter(OAUTH1)の両方が問題なく機能しているので、これを正確に行うことができましたが、Googleの場合、接続を作成しようとすると常に401応答が返されます。サーバーのコードは次のようになります。
AccessGrant accessGrant = new AccessGrant(accessToken);
connection = ((OAuth2ConnectionFactory<?>) connectionFactory).createConnection(accessGrant);
クライアントのコードは次のようになります。
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
console.log('ID: ' + profile.getId());
console.log('Name: ' + profile.getName());
console.log('Email: ' + profile.getEmail());
var access_token = googleUser.getAuthResponse().id_token;
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost/signin/google');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
console.log('Signed in as: ' + xhr.responseText);
console.log('access_token=' + access_token);
};
xhr.send('access_token=' + access_token);
}
後者のほとんどは、https://developers.google.com/identity/sign-in/web/backend-authにあるバックエンドサーバーで認証する方法に関するGoogleのドキュメントからコピーされています。
spring-social-google内の呼び出しをトレースしたところ、https://www.googleapis.com/oauth2/v2/userinfoへのREST呼び出しが発生しました。これは、401と次のJSONに応答する呼び出しです。
{
"error": {
"errors": [{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}],
"code": 401,
"message": "Invalid Credentials"
}
}
私はこの同じRESTAPIを自分で呼び出そうとしましたが、同じ応答が返されます。そのため、他のいくつかの投稿で読んだように、spring-social-googleがトークンを正しく送信しないという問題ではないようです。
この問題は、JavaScript APIが「id_token」を提供し、RESTAPIが「access_token」を期待しているという事実に何らかの形で関連していると思います。ただし、id_tokenとは別のものとしてアクセストークンを取得する方法が見つかりません。Googleのドキュメントはid_tokenをバックエンドに送信します。googleUser.getAuthResponse()で使用されている「id_token」プロパティの横に「access_token」プロパティがありますが、未定義で戻ってきます。このドキュメントはもちろん春の社会を対象としていないので、それが間違っていると言っているわけではありません。これを達成するための適切な方法は何か疑問に思っています。
id_tokenを処理できないことにより、spring-socialに問題がありますか?
access_tokenを取得するための明確な方法が見当たらないのは間違いですか?
とにかく、私はどういうわけか近いように感じますが、それでも解決策は十分に理解されていないようです。
ありがとうございました!
さて、私はそれを見つけました。全部書き留めておくと、脳内で何かがつまずいたようです...
問題は、実際には、id_tokenがaccess_tokenの代わりになることができないということです。私の好みでは、Googleのドキュメントは、表示されている例でこれについてもう少し明確になっている可能性がありますが、https://developers.google.com/identity/sign-in/web/の実際のクライアントリファレンスで説明されています。参照
キーはgetAuthResponse()のブールパラメータであり、これはオプションであり、デフォルトはfalseです。ドキュメントから:
includeAuthorizationDataオプション:アクセストークンとスコープを常に返すかどうかを指定するブール値。デフォルトでは、fetch_basic_profileがtrue(デフォルト値)の場合、アクセストークンと要求されたスコープは返されず、追加のスコープは要求されません。
私のJSでこれをtrueに設定すると、以前は定義されていなかったaccess_tokenフィールドにデータが入力され、このトークンを使用して/ oauth2 / v2 / userinfoエンドポイントにアクセスでき、spring-social-googleは他のプロバイダーと同じように正しく接続を作成できます。
これが少なくとも他の誰かに役立つことを願っています。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加