reactjs - 使用 Oauth2、React、Node.js 和 Passport.js 通过 Google 登录按钮对用户进行身份验证的最佳实践是什么?

标签 reactjs express authentication oauth-2.0 passport.js

我希望在我的网站上有一个登录按钮,这样当用户点击它时,用户就可以使用他们的 Google 凭据。我希望最好使用 Express.js 和 Passport.js 执行身份验证服务器端。

我实现了身份验证服务器端,但问题是我无法从网站向服务器发出 AJAX 请求来启动身份验证,因为 Google or Oauth don't support CORS 。因此,我需要在我的网站中使用 a href 元素来调用服务器身份验证端点。但是,我无法以这种方式捕获服务器响应。

如果我在客户端执行身份验证(我使用的是 React),我可以将登录状态存储在 Redux 中并允许用户访问网站的资源。但是,当用户注销时,我需要确保服务器端点停止为同一用户提供服务,这感觉就像实现两次身份验证:客户端和服务器端。

此外,在验证客户端时,Google 会打开一个弹出窗口供用户进行验证,我认为这比验证服务器端时的重定向更糟糕的用户体验。

我想知道使用 Oauth2/Google 进行身份验证的最佳实践是什么。例如,stackoverflow.com 也有 Google 按钮,但只是进行重定向,没有任何弹出窗口,所以我猜他们找到了一种执行服务器端身份验证并绕过 CORS 问题的方法。

最佳答案

我也遇到了同样的问题。本文为金币link

1.在auth路由文件中我有以下代码

 const CLIENT_HOME_PAGE_URL = "http://localhost:3000";

  // GET  /auth/google
  // called to authenticate using Google-oauth2.0
  router.get('/google', passport.authenticate('google',{scope : ['email','profile']}));


  // GET  /auth/google/callback
  // Callback route (same as from google console)
   router.get(
    '/google/callback',  
    passport.authenticate("google", {
    successRedirect: CLIENT_HOME_PAGE_URL,
    failureRedirect: "/auth/login/failed"
   })); 

   // GET  /auth/google/callback
  // Rest Point for React to call for user object From google APi
   router.get('/login/success', (req,res)=>{
     if (req.user) {
         res.json({
          message : "User Authenticated",
         user : req.user
        })
     }
     else res.status(400).json({
       message : "User Not Authenticated",
      user : null
    })
  });

2.在 React 端,当用户单击调用上述/auth/google api 的按钮后

  loginWithGoogle = (ev) => {
    ev.preventDefault();
    window.open("http://localhost:5000/auth/google", "_self");
  }

3.这将重定向到 Google 身份验证屏幕并重定向到/auth/google/callback,后者再次重定向到 React 应用主页 CLIENT_HOME_PAGE_URL

4.在首页调用用户对象的休息端点

(async () => {
  const request = await fetch("http://localhost:5000/auth/login/success", {
   method: "GET",
   credentials: "include",
   headers: {
    Accept: "application/json",
     "Content-Type": "application/json",
    "Access-Control-Allow-Credentials": true,
  },
});

const res = await request.json();
   //In my case I stored user object in redux store
   if(request.status == 200){
     //Set User in Store
    store.dispatch({
      type: LOGIN_USER,
      payload : {
        user : res.user
     }
    });
  }

})();

5.最后一件事在节点模块的 server.js/index.js 中添加 cors 包和以下代码

// Cors
app.use(
  cors({
    origin: "http://localhost:3000", // allow to server to accept request from different origin
    methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
    credentials: true // allow session cookie from browser to pass through
   })
);

关于reactjs - 使用 Oauth2、React、Node.js 和 Passport.js 通过 Google 登录按钮对用户进行身份验证的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55079181/

相关文章:

javascript - 防止在 React JS 中多次调用一个方法

reactjs - React - api 调用后重定向不起作用

node.js - express.static 处理根 url 请求

javascript - 使用 VueJS、VuelidateJS 和 NodeJS/Express 时的项目结构

java - 注销在 Spring Boot 应用程序中不起作用(不支持 POST 方法)

reactjs - Next.Js Redux Wrapper w/Typescript - 实现错误,存储类型不存在

html - React.renderToStaticMarkup 输出十六进制代码

javascript - 如何使用 Jest 在这种情况下测试 Express router catch 分支?

ios - 在 XCode 生成的单 View 应用程序中插入登录页面

javascript - 如何仅给定 Cognito 用户和具有完全 AWS 权限的安全服务器(安全后端服务器到服务器身份验证)来验证 Cognito 用户