Oauth2 Google 身份验证流程 - Next.JS / Express

2024-04-25

我正在使用 React/Next.Js 前端,并尝试通过 Google 的 Oauth2 策略实现身份验证。

我对这个过程感到非常困惑。

目前在客户端上,我有一个 Google 登录组件,其中包含客户端 ID,并且可以检索访问令牌。

      <GoogleLogin
            clientId="myclientid"
            buttonText="Login"
            onSuccess={userLogin}
            onFailure={userLogin}
            cookiePolicy={'single_host_origin'}
  />

然后我有一个函数,成功后会使用访问令牌向我的后端发送一条发布消息,如下所示:

export function googleAuthenticate(accessToken : string) : any{
    axios({
        method: 'post',
        url: "http://localhost:4000/auth/google",
        data: {
          accessToken: accessToken
        }
      })
    .then(res => {
        console.log(res);
    })
    .catch(err => {
        console.log("Failure!");
        console.log(err);
    })
};

在后端我使用护照,路线如下所示:

import express from 'express';
import passport from 'passport';
import Logger from '../logger/index';

const router = express.Router();

export function isAuthenticated(req:express.Request, res:express.Response, next : any) {
    return req.isAuthenticated() ?
        next() :
        res.sendStatus(401);
 }  

  router.get('/fail', (_req:express.Request, res:express.Response) => {
    res.json({ loginFailed: true });
  });

  router.post('/google', passport.authenticate('google', { scope: ['profile']}), (_req:express.Request, _res:express.Response) => {
    Logger.info("GET Request at Google Authentication endpoint received.");
  });

  router.get(
    '/google/callback',
    passport.authenticate('google', { failureRedirect: '/login' }),
    (_req:express.Request, res:express.Response) => {
      res.redirect('/graphql');
    }
  );

export default router;

我的护照模块如下所示:

module.exports = function(passport : any, GoogleStrategy : any){
  passport.use(new GoogleStrategy({
    clientID: config.google.client_id,
    clientSecret: config.google.client_secret,
    callbackURL: config.google.redirect_url
  },
  function(accessToken : string, profile : Profile, refreshToken : string, cb : any) {
    return cb(null, {
      id: profile.googleId,
      username: profile.email,
      image: profile.imageUrl,
      firstName: profile.givenName,
      surname: profile.familyName,
      accessToken: accessToken,
      refreshToken: refreshToken
    })
  }
  ));
}

由于 Next.js 是服务器端渲染的,因此我无法使用保存令牌。我知道我必须使用 cookie。但这是如何运作的呢?我无法从 Express 后端重定向客户端浏览器。

目前我只看到这两个错误:

OPTIONS https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2localhost:3000%2Fdashboard&scope=profile&client_id=687602672235-l0uocpfchbjp34j1jjlv8tqv7jadb8og.apps.googleusercontent.com 405

Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fbackoffice.dev.myos.co%2Fdashboard&scope=profile&client_id=687602672235-l0uocpfchbjp34j1jjlv8tqv7jadb8og.apps.googleusercontent.com' (redirected from 'http://localhost:4000/auth/google') from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

首先,我认为谷歌身份验证无法在本地主机上运行。
如果我正确理解你的服务器端逻辑,你可以轻松地将你的令牌保存为 cookie,然后在客户端中读取它们。

不确定护照,但你可以做类似的事情:
(我的应用程序正在使用此代码的实现)

前端 :

  <GoogleLogin
        clientId="myclientid"
        buttonText="Login"
        onSuccess={userLogin}
        onFailure={userLogin}
        cookiePolicy={'single_host_origin'}
/>

用户登录:

  async userLogin(response){
     var url = '/google-login/'+response.tokenObj.id_token
     fetch(url).then(/* i will handle response*/)
  }

然后在后台就可以使用google-auth-library登录或注册。
server.js:

const {OAuth2Client} = require('google-auth-library');
const GOOGLEID = "mygoogleid.apps.googleusercontent.com"
const client = new OAuth2Client(GOOGLEID);
var cookieParser = require('cookie-parser')

async function verify(userToken) {
    const ticket = await client.verifyIdToken({
    idToken: userToken,
    audience: "clientid.apps.googleusercontent.com",  // Specify the CLIENT_ID of the app that accesses the backend
   // Or, if multiple clients access the backend:
   //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]
  });
  const payload = ticket.getPayload();
  const userid = payload['sub'];
  return payload
  // If request specified a G Suite domain:
  //const domain = payload['hd'];
}

In server.js与此类似的路线:

   server.get('/google-login/:token',(req,res) => {
    const userToken =  req.params.token
    var  result =  verify(userToken).then(function(result){
      var userName = result.given_name
      var userSurname = result.family_name
      var userEmail = result.email
      /*
        Now user is authenticated i can send to the frontend
        user info or user token o save the token to session
      */
    }).catch(function(err){
      // error handling
    })
  })
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Oauth2 Google 身份验证流程 - Next.JS / Express 的相关文章

随机推荐

  • 浏览器选项卡存储?

    是否有一个浏览器存储只能由创建它的页面使用 我正在制作一个 TamperMonkey 脚本来自动化我的工作 当打开来自特定域的页面时会触发它 然后 它会在所述页面中找到特定链接 同一域 并在同一选项卡中将其打开 如果新打开的页面符合条件 则
  • 在 numpy 中快速找到对称对

    from itertools import product import pandas as pd df pd DataFrame from records product range 10 range 10 df df sample 90
  • PaintComponent() 正在其他组件上绘图

    我正在使用基于中的代码的自定义类这个答案 https stackoverflow com a 16909994 5686799 绘制一个形状像讲话泡泡的背景 每当我将应用程序的窗口大小调整到足以使组件在顶部或底部突出时 该组件的轮廓就会绘制
  • 有没有办法通过 PowerShell 检测声音?

    我想检测电脑是否正在播放任何类型的声音 如果它没有播放任何类型的声音 我可以在 Powershell 中使用其他条件并执行下一步需要执行的操作 那么有没有办法通过 PowerShell 来检测声音呢 Thanks 方法一 Import Mo
  • 如何声明二维数组?

    创建二维数组的最简单方法是什么 我希望能够做类似的事情 declare int d 0 m 0 n 您还可以通过指定数组的索引来创建关联数组或类似 哈希表 的数组 array array 0 gt array name gt John Do
  • Git:切换分支时保留忽略的文件

    我知道这看起来像是重复的GIT 切换分支时如何保留被忽略的文件 https stackoverflow com questions 15552959 git how to keep ignored files when switching
  • Tomcat 组件是什么?什么是卡塔利娜和郊狼? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 谁能描述一下 Tomcat 中的组件是什么 它在 Tomcat 服务器中的作用是什么 什么是郊狼 卡塔琳娜是什么 Catalina是T
  • 奇数运算符优先级/关联性行为[重复]

    这个问题在这里已经有答案了 在 Python 2 7 中 下面的内容是怎么回事 True w in what 两者的行为都不同 True w in what and True w in what gt gt gt True w in wha
  • 当你用 mlockall 设置的内存用完时会发生什么?

    我正在开发一个需要大量内存才能批量运行的 C 应用程序 gt 20GB 我的一些客户遇到了内存限制 有时操作系统开始交换 总运行时间加倍或更糟 我读到可以使用 mlockall 来防止进程被换出 当进程内存需求以这种方式接近或超过可用物理内
  • 如何在JPA中反映“嵌套集”模型

    很好用嵌套集 http www evanpetersen com item nested sets html对于分层数据 但在这个设计中 如果删除或插入一些数据 您应该始终计算右侧和左侧节点 此外 您没有任何外键 我如何用 JPA 反映这个
  • python模拟下面的return_value是什么

    我对 python 模拟很陌生 所以只是想理解它 在下面的代码中 下面指出的 1 和 2 语句之间有什么区别 因为最后我可以设置mock response status code与任一陈述 import requests def get d
  • Safari - 视频加载速度太慢

    我在将视频添加到我的网站时遇到了一些麻烦 我使用这段代码
  • 使用自己的路径在不同的 python 可执行文件下生成 multiprocessing.Process

    我有两个版本的Python 实际上是两个conda环境 path to bin 1 python path to bin 2 python 我想从一个版本的 python 启动一个在另一个版本中运行的函数 使用类似multiprocessi
  • 敲除验证

    我有一个 asp net mvc3 项目 我在其中使用淘汰赛绑定对表进行批量编辑 我想在保存数据时进行必需验证和数字验证等验证 有没有更简单的方法来进行淘汰验证 PS 我没有使用表格 看一下敲除验证 https github com eri
  • 井字游戏的极小极大

    我正在尝试用简单的极小极大算法来解决井字游戏 简单 但应该涵盖很多语言 到目前为止我所拥有的 该板表示为 9 个 未绑定 变量的数组 这些变量可以设置为x or o 获胜条件基本上是 win Player X1 X2 X3 X1 Playe
  • 如何在 IAR EWARM 5.4 中抑制警告(从错误转换)

    我有一个用于日志记录的宏 它接受可变数量的参数 该宏将由 GCC 在非嵌入式上下文中处理 并扩展为有效的 C 代码 尽管如此 无论我在何处调用宏 数千个位置 IAR EWARM 都会给出错误 Pe054 宏调用中的参数太少 EWARM 确实
  • AngularJS 阻止 symfony2 表单中的提交按钮

    我在 symfony2 中创建了表单 最后呈现了提交表单的按钮 当我添加ng app myApp 一切正常 但我无法提交此页面上的表单 为什么会这样以及如何解锁 FORM gt add company choice array mapped
  • NSAssert 与断言:您使用哪个以及何时使用?

    最近 我读到了两条非常有趣的建议 在评论中这个 StackOverflow 答案 https stackoverflow com questions 1375786 whats the point of nsassert actually
  • 如何将多个身份验证提供商链接到 Firebase 帐户?

    我无法成功执行此操作 我按照 Firebase 文档上的说明执行了以下步骤 使用现有的身份验证提供程序登录使用 我的案例 脸书 完成新身份验证提供程序的登录流程 直至 但不包括 调用其中之一Auth signInWith方法 我的情况 我想
  • Oauth2 Google 身份验证流程 - Next.JS / Express

    我正在使用 React Next Js 前端 并尝试通过 Google 的 Oauth2 策略实现身份验证 我对这个过程感到非常困惑 目前在客户端上 我有一个 Google 登录组件 其中包含客户端 ID 并且可以检索访问令牌