У меня есть веб-страница, использующая 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, и они привели к вызову REST к https://www.googleapis.com/oauth2/v2/userinfo, который отвечает 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 не отправляет токен должным образом, как я читал в некоторых других сообщениях.
Я считаю, что проблема как-то связана с тем фактом, что API JavaScript дает мне «id_token», а API REST ожидает «access_token». Однако я не нахожу способа получить токен доступа как нечто отдельное от id_token, и документация Google действительно отправляет id_token в серверную часть. Существует свойство «access_token» наряду с используемым свойством «id_token» в googleUser.getAuthResponse(), но оно возвращается неопределенным. Этот документ, конечно, не предназначен для весенних социальных сетей, поэтому я не говорю, что он неверен, мне просто интересно, как этого добиться.
Виноват ли spring-social в том, что не может справиться с id_token?
Я виноват, что не вижу ясного способа получить access_token?
Во всяком случае, я чувствую, что я как-то близок, но все же решение кажется далеким от понимания.
Благодарю вас!