我有一个使用 PHP/JavaScript 的网页,可以在客户端成功执行 Google 登录过程。然后我想将获得的令牌转发到使用 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);
}
后者的大部分内容是从 Google 文档中复制的,关于如何使用此处找到的后端服务器进行身份验证:https ://developers.google.com/identity/sign-in/web/backend-auth
我跟踪了 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"
}
}
我自己尝试调用这个相同的 REST API,我也得到了相同的响应,所以这似乎不是 spring-social-google 没有正确发送令牌的问题,正如我在其他一些帖子中所读到的那样。
我相信这个问题在某种程度上与 JavaScript API 给我一个“id_token”而 REST API 期待一个“access_token”的事实有关。但是,我没有找到一种方法来获取与 id_token 不同的访问令牌,并且 Google 文档确实将 id_token 发送到后端。在 googleUser.getAuthResponse() 中使用的“id_token”属性旁边有一个“access_token”属性,但它返回未定义。这个文档当然不是针对 spring-social 所以我并不是说它是不正确的,我只是想知道实现这一目标的正确方法是什么。
由于无法处理 id_token,spring-social 是否有过错?
我没有看到一些明确的方法来获取 access_token 吗?
无论如何,我觉得我有点接近,但解决方案似乎仍然无法掌握。
谢谢!