使用从JavaScript客户端收到的令牌在服务器上创建社交连接

时间:2018-05-31 19:53:46

标签: access-token google-signin spring-social spring-social-google

我有一个使用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?

无论如何,我觉得我在某种程度上接近但仍然没有把握解决方案。

谢谢!

1 个答案:

答案 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可以正确创建连接,就像其他提供者。

我希望这至少可以帮助别人。

相关问题