我有一个使用PHP / JavaScript的网页,可以在客户端成功完成Google Signin流程。然后,我想将获得的令牌转发到后端,后端使用Spring-Social创建社交连接,并能够调用已授权应用的API。 我设法做到这一点,Facebook(OAUTH2)和Twitter(OAUTH1)都完美地工作,但对于谷歌,我总是在尝试创建连接时获得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没有正确发送令牌的问题,因为我&#39;我读过其他一些帖子。
我认为这个问题在某种程度上与JavaScript API给我一个&#34; id_token&#34;并且REST API期待&#34; access_token&#34;。但是,我没有找到一种方法来获取访问令牌作为与id_token分开的内容,而Google文档确实将id_token发送到后端。有一个&#34; access_token&#34;物业旁边使用的&#34; id_token&#34; googleUser.getAuthResponse()中的属性,但它未定义。 这个文档当然不是针对spring-social,所以我并不是说它不正确,我只是想知道实现这个目的的正确方法是什么。
由于无法处理id_token,春天社交是否有问题?
我有没有看到一些明确的方法来获取access_token?
无论如何,我觉得我在某种程度上接近但仍然没有把握解决方案。
谢谢!
答案 0 :(得分:0)
好吧,我找到了。看起来写下整件事真的让我大脑中的东西绊了......
问题实际上是id_token不能取代access_token。根据我的口味,谷歌文档在他们展示的示例中可能会更加明确,但他们最终会在https://developers.google.com/identity/sign-in/web/reference
的实际客户参考中解释它。键是getAuthResponse()的布尔参数,它是可选的,默认为false。来自doc:
includeAuthorizationData可选:指定是否的布尔值 始终返回访问令牌和范围。默认情况下,访问权限 fetch_basic_profile时不返回令牌和请求的作用域 为true(默认值),不请求其他范围。
通过在我的JS中将此设置为true,填充了之前未定义的access_token字段,使用此标记可以访问/ oauth2 / v2 / userinfo端点,spring-social-google可以正确创建连接,就像其他提供者。
我希望这至少可以帮助别人。