node.js - 带有 Node js 的谷歌 oauth2

标签 node.js vue.js google-oauth

我有一个 Vuejs 应用程序,我正在尝试添加 google 身份验证。我用这个插件https://www.npmjs.com/package/vue-google-oauth2在前端生成授权码,然后将其发送到我的后端,以便它可以获得用户凭据。

这是前端的代码:

<script>
import axios from "axios";
export default {
  methods: {
    googleAuth() {
      this.$gAuth
        .getAuthCode()
        .then(authCode => {
          //on success
          axios.post('my-back-end', {code:authCode, redirect_uri: 'postmessage'}).then(res=>{
              console.log(res);
          });
        })
        .catch(error => {
          //on fail do something
        });
    }
  }
};
</script>

我成功获得了授权码,直到这里,我将它发送到我的后端,它是根据官方谷歌文档用 node.js 编写的。 https://github.com/googleapis/google-api-nodejs-client#oauth2-client

我有这条路线:

router.post('/google', googleController.getGoogleAccountFromCode);

还有这个 Controller :

const {google} = require('googleapis');

const oauth2Client = new google.auth.OAuth2(
    process.env.GOOGLE_CLIENT_ID,
    process.env.GOOGLE_CLIENT_SECRET,
    process.env.GOOGLE_REDIRECT_URL
);

exports.getGoogleAccountFromCode = (req, res, next) => {
   const code = req.body.code;
   const data = oauth2Client.getToken(code)
    .then(res => {
        console.log(res);
    })
    .catch(err=>{
        console.log(err);
    });
};

我得到这个错误:

{ Error: invalid_request at Gaxios.request (/home/monkeydkon/Desktop/tabata-rest/node_modules/gaxios/build/src/gaxios.js:70:23) at process._tickCallback (internal/process/next_tick.js:68:7) response: { config: { method: 'POST', url: 'https://oauth2.googleapis.com/token', data: 'code=4%2FlgGDaumBZrCEo1GraV2csRBqKMOQFM7IKhBUP3tJVf2NSPS2nBqbdc9mDqIuaM847ZIPy6mZ4MGHLD9fR2a3A_Q&client_id=918021882776-fu8hr3q5ld81t1dlv1pd8en7ht8hu3t6.apps.googleusercontent.com&client_secret=LBCef5d7K48XGB7TEEDF7SBK&redirect_uri=%2Fauth%2Fgoogle%2Fredirect&grant_type=authorization_code&code_verifier=', headers: [Object], params: [Object: null prototype] {}, paramsSerializer: [Function: paramsSerializer], body: 'code=4%2FlgGDaumBZrCEo1GraV2csRBqKMOQFM7IKhBUP3tJVf2NSPS2nBqbdc9mDqIuaM847ZIPy6mZ4MGHLD9fR2a3A_Q&client_id=918021882776-fu8hr3q5ld81t1dlv1pd8en7ht8hu3t6.apps.googleusercontent.com&client_secret=LBCef5d7K48XGB7TEEDF7SBK&redirect_uri=%2Fauth%2Fgoogle%2Fredirect&grant_type=authorization_code&code_verifier=', validateStatus: [Function: validateStatus], responseType: 'json' }, data: { error: 'invalid_request', error_description: 'Invalid parameter value for redirect_uri: Missing scheme: /auth/google/redirect' }, headers: { 'alt-svc': 'quic=":443"; ma=2592000; v="46,43,39"', 'cache-control': 'private', connection: 'close', 'content-encoding': 'gzip', 'content-type': 'application/json; charset=utf-8', date: 'Wed, 31 Jul 2019 20:47:01 GMT', server: 'scaffolding on HTTPServer2', 'transfer-encoding': 'chunked', vary: 'Origin, X-Origin, Referer', 'x-content-type-options': 'nosniff', 'x-frame-options': 'SAMEORIGIN', 'x-xss-protection': '0' }, status: 400, statusText: 'Bad Request' }, config: { method: 'POST', url: 'https://oauth2.googleapis.com/token', data: 'code=4%2FlgGDaumBZrCEo1GraV2csRBqKMOQFM7IKhBUP3tJVf2NSPS2nBqbdc9mDqIuaM847ZIPy6mZ4MGHLD9fR2a3A_Q&client_id=918021882776-fu8hr3q5ld81t1dlv1pd8en7ht8hu3t6.apps.googleusercontent.com&client_secret=LBCef5d7K48XGB7TEEDF7SBK&redirect_uri=%2Fauth%2Fgoogle%2Fredirect&grant_type=authorization_code&code_verifier=', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'google-api-nodejs-client/4.2.6', Accept: 'application/json' }, params: [Object: null prototype] {}, paramsSerializer: [Function: paramsSerializer], body: 'code=4%2FlgGDaumBZrCEo1GraV2csRBqKMOQFM7IKhBUP3tJVf2NSPS2nBqbdc9mDqIuaM847ZIPy6mZ4MGHLD9fR2a3A_Q&client_id=918021882776-fu8hr3q5ld81t1dlv1pd8en7ht8hu3t6.apps.googleusercontent.com&client_secret=LBCef5d7K48XGB7TEEDF7SBK&redirect_uri=%2Fauth%2Fgoogle%2Fredirect&grant_type=authorization_code&code_verifier=', validateStatus: [Function: validateStatus], responseType: 'json' }, code: '400' }

我真的看不懂谷歌文档。没有对 oauth2 的适当支持。我真的需要一些帮助。 谢谢

最佳答案

我之前也被这个问题卡住了。您的前端代码看起来不错。您只是在后端遗漏了一些东西。

试着把你的 Controller 改成这个

const {google} = require('googleapis');

exports.getGoogleAccountFromCode = (req, res, next) => {
    const code = req.body.code;
    const oauth2Client = new google.auth.OAuth2(process.env.GOOGLE_CLIENT_ID, process.env.GOOGLE_CLIENT_SECRET, 'postmessage');
    google.options({ auth: oauth2Client });


    oauth2Client.getToken(code).then(res => {
        const tokens = res.tokens;
        oauth2Client.setCredentials(tokens);
        const oauth2 = google.oauth2({ version: 'v2' });
        return oauth2.userinfo.get();
    })
        .then(userData => {
            console.log(userData);
        })
        .catch(err => {
            console.log(err);
        });
};

您实际上错过的只是 google.options。然后,您提取 token 和用户信息。你应该能够用它们做你想做的事。

也不要忘记在测试时(例如使用 POSTMAN)总是为每次尝试发送一个新的 code

关于node.js - 带有 Node js 的谷歌 oauth2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57298646/

相关文章:

node.js - 找不到模块

javascript - VueJ在Vuetify的简单表上重新加载

javascript - 如何获取对象值

spring - 使用谷歌不记名 token 访问我的 api

ruby-on-rails - 无法从 GoogleOauth2 对您进行身份验证,因为 "Authenticity error"

javascript - 使用 bluebird Promise 时,then() 没有被调用

javascript - 如何从 JavaScript 检查 session 是否存在

javascript - 在 node.js 中使用 partials 和 express

javascript - 在 Vue.js 中监听自定义事件

oauth-2.0 - 如何在Google OAuth 2中获取Gmail帐户的创建日期