Что у меня пока что приложение перенаправляет на страницу согласия. Пользователь соглашается, а затем меня перенаправляют обратно на localhost с действующим кодом авторизации. Насколько я понимаю, мне нужно сделать еще один звонок и обменять этот код на токен доступа. Однако getAccessToken() не работает. Журнал консоли возвращает это:
invalid_client
invalid_request
Пожалуйста, дайте мне знать, какая дополнительная информация необходима.
Вот соответствующий код:
var { google } = require('googleapis');
var http = require("http");
var request = require('request');
var oauth2Client = new google.auth.OAuth2(
'<My Client ID>',
'<My Client Secret>',
'http://localhost:8080'
);
exports.generateAuthCodeUrl = function () {
const url = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: 'https://www.googleapis.com/auth/blogger'
});
return url;
};
exports.getAccessToken = function (accessCode) {
var codeOptions = {
code: accessCode
}
oauth2Client.getToken(codeOptions, function (err, tokens) {
// Now tokens contains an access_token and an optional refresh_token. Save them.
if (!err) {
oauth2Client.setCredentials(tokens);
return tokens;
}
console.info(err.message);
});
};
Я прочитал связанную статью из ответа pinoyyid ДВАЖДЫ, а также отметил шаги, перечисленные в его ответе. Перечисление простых шагов помогло мне понять более четко. Также, как рекомендовано в комментариях, Я удалил библиотеку googleapi (Вышеупомянутая ошибка возникла в коде этой библиотеки.) просто делал регулярные вызовы необходимых конечных точек с библиотекой request. Я использовал request, потому что он гораздо менее подробный. Код, который у меня получился, выглядит так:
exports.generateAuthCodeUrl = function () {
var authURL = "https://accounts.google.com/o/oauth2/v2/auth?" +
"client_id = " + client_id +
"&scope = " + scope +
"&redirect_uri = " + redirect_uri +
"&response_type = " + response_type;
//redirect to consent page
return authURL;
};
exports.getAccessToken = function (x) {
var postDataUrl = 'https://www.googleapis.com/oauth2/v4/token?' +
'code=' + x + //auth code received from the previous call
'&client_id=' + client_id +
'&client_secret=' + client_secret +
'&redirect_uri=' + redirect_uri +
'&grant_type=' + "authorization_code"
var options = {
uri: postDataUrl,
method: 'POST'
};
request(options, function (err, res, body) {
return body; //returns an object with an access token!!!
});
};
Очень рад, что это работает !! Большое спасибо всем вам
@programoholic В настоящее время ищу ответ в чистом виде. Но может обновиться в будущем, если мы пойдем экспрессом и паспортным маршрутом.
мой 2c, выбросьте библиотеку и напрямую вызовите конечные точки. Это одно перенаправление для получения кода аутентификации, а затем простой вызов REST для обмена на токен доступа / обновления. Если у вас есть какие-либо проблемы, вы можете сравнить свой HTTP-запрос с запросом от Google OAuth, чтобы увидеть, что вы делаете не так.
@pinoyyid Звучит неплохо. Попробую без библиотеки.
В случае, если это поможет, я опубликовал Dummy's Guide to Oauth в качестве ответа, чтобы изложить шаги.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я написал эту библиотеку, чтобы получить информацию о пользователях, надеюсь, это поможет.
'use strict'
const { google } = require('googleapis')
const credentials = require('../configs/config').google
class googleApi {
constructor(){
const {client_id, client_secret, redirectUri } = credentials;
this.oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirectUri)
}
generateUrl(scopes){
const url = this.oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: scopes.join(' ')
})
return url;
}
async getUserInfo(code){
const credentials = await this.oAuth2Client.getToken(code)
this.oAuth2Client.setCredentials(credentials.tokens);
const plus = google.plus({
version: 'v1',
auth: this.oAuth2Client,
});
const data = await plus.people.get({userId: 'me'});
return data;
}
}
module.exports = new googleApi();
и это реализация:
'use strict'
const googleApi = require('../libs/google');
exports.requestGmailAuth = function (req, res, next){
let url = googleApi.generateUrl(scopes)
res.redirect(url);
}
exports.getGmailUserInfo = async function (req, res, next){
const qs = new url.URL(req.url, 'http://localhost:3000').searchParams;
let code = qs.get('code')
if (!code){
next(new Error('No code provided'))
}
googleApi.getUserInfo(code)
.then(function(response){
res.send(response.data)
}).catch(function(e){
next(new Error(e.message))
})
}
это маршруты:
app.get('/request/gmail/auth', user.requestGmailAuth)
app.get('/get/gmail/user', user.getGmailUserInfo)
Когда / request / gmail / auth получает запрос, он перенаправляет на страницу согласия, тогда страница согласия перенаправляется на / get / gmail / user с параметром «code».
попробуйте этот сниппет, и если проблема не исчезнет, проверьте свой идентификатор клиента и секрет клиента, а также убедитесь, что у вас включен google plus api на панели инструментов разработчика.
Думаю, это чистая реализация. Раньше я использовал что-то очень похожее. Но у меня была проблема. Как выйти из системы пользователя? потому что в браузере, особенно в Chrome, я думаю, после того, как пользователь входит в Google, идентификатор сохраняется, и поэтому он автоматически входит в систему этого пользователя и пропускает возможность выбора другого идентификатора.
Руководство для пустышки по трехстороннему Google OAuth.
Буквально все, что вам нужно знать, есть на этой единственной странице https://developers.google.com/identity/protocols/OAuth2WebServer. Прочтите его дважды, и вы станете ниндзя OAuth. Таким образом, в нем говорится ...
client_id для идентификации вашего приложенияscope, чтобы сказать, какие разрешения вы запрашиваетеredirect_uri, чтобы сообщить Google, куда перенаправить браузер пользователя с результатомresponse_type=code, чтобы сказать, что вам нужен код авторизацииredirect_uri вашего приложения с параметром запроса code, который является одноразовым кодом аутентификации.Если вы перейдете к https://developers.google.com/oauthplayground/, вы можете выполнить действия в Интернете, чтобы увидеть, как выглядят различные URL-адреса и ответы.
Принял это как правильный ответ, потому что это помогло мне больше всего. Спасибо @pinoyyid!
Обновил свой пост на основе вашего ответа. Еще раз спасибо, это помогло.
если вы можете использовать password.js, дайте мне знать .. я могу помочь