使用Node JS对Google API进行身份验证

时间:2019-01-08 17:53:55

标签: javascript node.js google-api google-oauth

到目前为止,我的应用程序将重定向到同意页面。用户接受,然后使用有效的授权代码将我重定向回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.log(err.message);
    });
};

摘要以及对我有用的内容

我阅读了pinoyyid的答案TWICE中的链接文章,还注意到了他的答案中列出的步骤。列出简单的步骤有助于我更清楚地理解。另外,按照评论中的建议,我删除了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!!!
    });
};

很高兴我能完成这项工作!!非常感谢你们

2 个答案:

答案 0 :(得分:11)

3腿Google OAuth虚拟指南。

从字面上看,您需要了解的所有内容都在此单一页面https://developers.google.com/identity/protocols/OAuth2WebServer上。阅读两次,您将成为OAuth忍者。总之,它说...

  1. 使用4个查询参数构造一个account.google.com网址:-
    1. client_id来标识您的应用
    2. scope说出您要求的权限
    3. redirect_uri告诉Google将结果重定向到用户浏览器的位置
    4. response_type=code说您想要验证码
  2. 将用户的浏览器重定向到该URL
  3. 在用户登录时喝一口咖啡,选择他的Google帐户并授予权限,直到最终...
  4. 用户的浏览器重定向到应用程序的redirect_uri,查询参数为code,这是一次性的Auth Code。
  5. 将身份验证代码发布到Google的令牌端点
  6. 解析JSON响应以获取访问令牌
  7. 在“ authorization:bearer access_token” http标头中使用访问令牌,以用于后续的Google API请求

如果您转到https://developers.google.com/oauthplayground/,则可以在线完成所有步骤,以查看各种URL和响应的样子。

答案 1 :(得分:1)

我写了这个库来获取用户信息,希望对您有所帮助。

'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收到请求后,它将重定向到同意页面,然后同意页面使用“ code”参数重定向到/ get / gmail / user。

尝试此摘要,如果问题仍然存在,请检查您的客户端ID和客户端机密,并确保在开发人员信息中心中启用了google plus api。