Problema CORS al realizar una solicitud AJAX desde la aplicación React> Servidor de nodo> redirigir a la autenticación de Google OAuth2

Hola a todos, me he estado golpeando la cabeza investigando esto durante los últimos 2 días sin suerte.

Este es el error que obtengo al intentar autenticar con la estrategia de pasaportes de Google Oauth2 desde mi aplicación React @localhost: 3000. Estoy ejecutando una aplicación separada con un servidor de nodo / expreso en localhost: 3001.

XMLHttpRequest no puede cargar http: localhost: 3001 / api / auth / google / login. Redirigir de ‘http: localhost: 3001 / api / auth / google / login’ a ‘https: accounts.google.com/o/oauth2/v2/auth? Response_type = code & redirect_uri = http% 3A% 2F% 2Flocalhost% 3A3001% 2Fapi % 2Fauth% 2Fgoogle% 2Fcallback & scope = https% 3A% 2F% 2Fmail.google.com & client_id = ***. Apps.googleusercontent.com ‘ha sido bloqueado por la política de CORS: no hay ningún encabezado’ Acceso-Control-Permitir-Origen ‘presente El recurso solicitado. Origen ‘http: localhost: 3000’ por lo tanto, no se permite el acceso.

createError.js:16 

Error no detectado (en promesa): Error de red en createError (createError.js: 16) en XMLHttpRequest.handleError (xhr.js: 87)

Este es el código que estoy usando en mi cliente para intentar iniciar sesión desde uno de mis componentes:

// BOTÓN

 

// METODO DE COMPONENTES ESTATUOS

 googleAuth() { axios.get("http:localhost:3001/api/auth/google/login").then(res => { console.log("GOOGLE OAUTH 2 RES", res); }); } 

// CONTROLADOR

 passport.use( new GoogleStrategy( { clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, callbackURL: "/api/auth/google/callback", accessType: "offline" }, (accessToken, refreshToken, profile, done) => { const info = { googleUsername: profile.displayName, googleAccessToken: accessToken, googleRefreshToken: refreshToken, googleEmail: profile.emails[0].value }; User.findOrCreate({ where: { googleId: profile.id }, defaults: info }) .spread(user => { if (user) return done(null, user.toAuthJSON); // this is method that returns a signed JWT off user DB instance. return done(null, false); }) .catch(done); } ) ); // GOOGLE LOGIN router.get( "/login", passport.authenticate("google", { scope: [ "https://mail.google.com/", "https://www.google.com/m8/feeds/", "email", "profile" ] }) ); // GOOGLE CALLBACK router.get( "/callback", passport.authenticate("google", { session: false, }), (req, res) => { res.json(req.user.token) } ); 

Pasos que ya he tomado para tratar de resolver:

  • Deshabilité CORS en mi navegador
  • Probé el módulo cors npm en mis rutas / api en el lado del servidor. Nada parece funcionar.
  • Y muchos otros retoques y desesperación …

  • Basado en el error, Google me está impidiendo hacer una solicitud en sentido descendente desde mi servidor y lanzar el error (creo) …

Cuáles son mis metas:

  • Quiero que Google devuelva un objeto de usuario, que luego almaceno en mi base de datos (lógica ya codificada para esto)
  • En lugar de tener el servidor res.redirect (), quiero res.json () un JWT firmado (que ya he conectado correctamente).
  • No quiero usar autenticación basada en sesión en mi servidor y mantener las cosas limpias y sin estado.

¿Esto es posible? También se debe tener en cuenta que tengo una configuración de entorno de desarrollo:

Inicio del servidor con simultáneo (inicia el servidor cliente y nodemon simultáneamente – cliente @ localhost: 3000 realiza solicitudes de proxy al servidor @ localhost: 3001) – ¿no está seguro si esto podría estar causando algún problema?

Cualquier ayuda sería muy apreciada!

Así que pude resolver el problema. El problema es que estás usando passport.js para la autenticación social, cuando podrías haber usado algo simple como

https://www.npmjs.com/package/react-social-login

Pero de todos modos le diría cómo hacer que su proyecto actual funcione.

https://github.com/j-mcfarlane/Reactjs-SocialAuth-RESTAPI

Debe tener la redirección a la interfaz de usuario y no a la API. Así que tu configuración cambiará como abajo

 googleCallbackURL: 'http://localhost:3000https://stackoverflow.com/api/auth/google/callback' 

A continuación, en su callback, en lugar de devolver datos, devolverá una redirección como la siguiente

 jwt.sign(payload, secret, { expiresIn: 220000 }, (err, token) => { if (err) return console.log(err) res.redirect("http://localhost:3000/login?token=" + token); }) 

He codificado para localhost:3000 pero debe obtener el host de la solicitud y luego usarlo.

A continuación, actualizará su App.js para agregar otra ruta para /login , que llamará a un componente SocialLogin

 import React, { Component, Fragment } from 'react' import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' import PrivateRoute from '../util/PrivateRoute' // Components import Navbar from './layout/Navbar' import Landing from './Landing' import SocialLogin from './SocialLogin' import Dashboard from './Dashboard' class App extends Component { render() { return (   
) } } export default App

El SocialLogin más SocialLogin que escribí está abajo.

 import React from 'react' import qs from 'query-string' const SocialLogin = (props) => { console.log(props.location.search) let params = qs.parse(props.location.search) window.localStorage.setItem('token', params['token']) return (
Landing Page - {params.token}
) } export default SocialLogin

Aquí tienes el token y puedes continuar el flujo de la forma que más te guste. También en Google.js he cambiado a continuación

  

de nuevo a tu comentario

 Log in with google 

Necesita redireccionamientos para funcionar y no debe usar AJAX en su llamada de autenticación de google.

Ahora, después de todas estas correcciones, puedo obtener el token como se muestra a continuación

Token en la interfaz de usuario