Аутентифицироваться в Google API с помощью Node JS

Что у меня пока что приложение перенаправляет на страницу согласия. Пользователь соглашается, а затем меня перенаправляют обратно на 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!!!
    });
};

Очень рад, что это работает !! Большое спасибо всем вам

если вы можете использовать password.js, дайте мне знать .. я могу помочь

programoholic 10.01.2019 20:06

@programoholic В настоящее время ищу ответ в чистом виде. Но может обновиться в будущем, если мы пойдем экспрессом и паспортным маршрутом.

KidBilly 10.01.2019 20:48

мой 2c, выбросьте библиотеку и напрямую вызовите конечные точки. Это одно перенаправление для получения кода аутентификации, а затем простой вызов REST для обмена на токен доступа / обновления. Если у вас есть какие-либо проблемы, вы можете сравнить свой HTTP-запрос с запросом от Google OAuth, чтобы увидеть, что вы делаете не так.

pinoyyid 11.01.2019 20:02

@pinoyyid Звучит неплохо. Попробую без библиотеки.

KidBilly 11.01.2019 22:23

В случае, если это поможет, я опубликовал Dummy's Guide to Oauth в качестве ответа, чтобы изложить шаги.

pinoyyid 11.01.2019 23:19
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
13
5
7 103
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я написал эту библиотеку, чтобы получить информацию о пользователях, надеюсь, это поможет.

'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, идентификатор сохраняется, и поэтому он автоматически входит в систему этого пользователя и пропускает возможность выбора другого идентификатора.

sakib11 01.08.2020 22:31
Ответ принят как подходящий

Руководство для пустышки по трехстороннему Google OAuth.

Буквально все, что вам нужно знать, есть на этой единственной странице https://developers.google.com/identity/protocols/OAuth2WebServer. Прочтите его дважды, и вы станете ниндзя OAuth. Таким образом, в нем говорится ...

  1. Создайте URL-адрес accounts.google.com с 4 параметрами запроса: -
    1. client_id для идентификации вашего приложения
    2. scope, чтобы сказать, какие разрешения вы запрашиваете
    3. redirect_uri, чтобы сообщить Google, куда перенаправить браузер пользователя с результатом
    4. response_type=code, чтобы сказать, что вам нужен код авторизации
  2. перенаправить браузер пользователя на этот URL
  3. Выпейте кофе, пока пользователь входит в систему, выбирает свою учетную запись Google и предоставляет разрешение, пока в конце концов ...
  4. Браузер пользователя перенаправляется обратно на redirect_uri вашего приложения с параметром запроса code, который является одноразовым кодом аутентификации.
  5. Отправьте код аутентификации в конечную точку токена Google
  6. Разберите ответ JSON, чтобы получить токен доступа
  7. Используйте токен доступа в http-заголовке «authorization: bearer access_token» для последующих запросов Google API.

Если вы перейдете к https://developers.google.com/oauthplayground/, вы можете выполнить действия в Интернете, чтобы увидеть, как выглядят различные URL-адреса и ответы.

Принял это как правильный ответ, потому что это помогло мне больше всего. Спасибо @pinoyyid!

KidBilly 16.01.2019 15:41

Обновил свой пост на основе вашего ответа. Еще раз спасибо, это помогло.

KidBilly 17.01.2019 16:41

Другие вопросы по теме