Аутентификация через Passport. js со сторонним (разногласия) на React работает локально, но не при размещении на Heroku - PullRequest
0 голосов
/ 18 апреля 2020

Я пытался реализовать вход с разногласиями, используя Passport js, и мне удалось заставить его работать локально (частично, у меня проблемы с перенаправлением после обратного вызова, поэтому сейчас я вручную перенаправляю обратно на целевую страницу @ "/"), успешно перенаправив на https://discordapp.com/oauth2/authorize ... и все. Однако, когда он размещен на Heroku, он больше не работает. В адресной строке отображается правильный адрес «/ auth / discord», но отображается только пустая страница.

Я пытался использовать LinkContainers из response-router- bootstrap, играя с Nav.Item и Nav.Link с реакции- bootstrap, включил и выключил CORS, изменил порядок маршрутов на стороне сервера, используя только теги привязки, настроив область запроса на аутентификацию и некоторые другие вещи, которые Я не могу вспомнить сейчас. Ничто, кажется, не имеет значения все же. Должно быть, я лаю не на те деревья.

Буду очень признателен за любые подсказки относительно того, на что мне следует смотреть. Пожалуйста, найдите мой код ниже:

Приложение. js

import React, { useEffect } from "react";
import { Switch, Route } from "react-router-dom";
import { connect } from "react-redux";

import { checkUserSession } from "./redux/user/user.actions";

import Header from "./components/header/header.component";
const Landing = () => <h2>Landing</h2>;
const FrontTest = () => <h2>FrontTest</h2>;

const App = ({ checkUserSession, currentUser }) => {
  useEffect(() => {
    checkUserSession();
  }, [checkUserSession]);

  return (
    <div>
      <Header />
      <Switch>
        <Route exact path="/" component={Landing} />
        <Route exact path="/fronttest" component={FrontTest} />
      </Switch>
    </div>
  );
};

const mapStateToProps = ({ user: { currentUser } }) => ({
  currentUser,
});

const mapDispatchToProps = (dispatch) => ({
  checkUserSession: () => dispatch(checkUserSession()),
});

export default connect(mapStateToProps, mapDispatchToProps)(App);

header.component.jsx

import React from "react";
import { connect } from "react-redux";

import Navbar from "react-bootstrap/Navbar";
import Nav from "react-bootstrap/Nav";
import Button from "react-bootstrap/Button";

import DiscordSignin from "../discord-signin/discord-signin.component";

import { signOutStart } from "../../redux/user/user.actions";

const Header = ({ currentUser, signOutStart }) => (
  <Navbar bg="dark" variant="dark" fixed="sticky-top" expand="sm">
    <Navbar.Brand href="/">Race League</Navbar.Brand>
    <Navbar.Toggle aria-controls="basic-navbar-nav" />
    <Navbar.Collapse id="basic-navbar-nav">
      <Nav className="mr-auto">
        <Nav.Link href="/fronttest">FrontTest</Nav.Link>
      </Nav>
      {currentUser ? (
        <Button onClick={signOutStart} variant="outline-danger">
          Sign out
        </Button>
      ) : (
        <Nav.Link href="/auth/discord">
          <DiscordSignin />
        </Nav.Link>
      )}
    </Navbar.Collapse>
  </Navbar>
);

const mapStateToProps = ({ user: { currentUser } }) => ({
  currentUser,
});

const mapDispatchToProps = (dispatch) => ({
  signOutStart: () => dispatch(signOutStart()),
});

export default connect(mapStateToProps, mapDispatchToProps)(Header);

сервер. js

const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const path = require("path");
const compression = require("compression");
const enforce = require("express-sslify");

const passport = require("passport");

if (process.env.NODE_ENV !== "production") require("dotenv").config();

require("./models/User");
require("./services/passport");

const app = express();
const PORT = process.env.PORT || 5000;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());

app.use(cors());

app.use(passport.initialize());

require("./routes/authRoutes")(app);

if (process.env.NODE_ENV === "production") {
  app.use(compression());
  app.use(enforce.HTTPS({ trustProtoHeader: true }));
  app.use(express.static(path.join(__dirname, "client/build")));

  app.get("*", (req, res) => {
    res.sendFile(path.join(__dirname, "client/build", "index.html"));
  });
}

app.listen(PORT, (error) => {
  if (error) throw error;
  console.log("Server running on port " + PORT);
});

authRoutes. js

const passport = require("passport");
const jwt = require("jsonwebtoken");

module.exports = app => {
  app.get("/auth/discord", passport.authenticate("discord"));

  app.get("/auth/discord/callback", (req, res) => {
    passport.authenticate(
      "discord",
      {
        failureRedirect: "/",
        session: false
      },
      (error, user) => {
        if (error || !user) {
          res.status(400).json({ error });
        }

        // jwt content
        const payload = {
          ...user,
          expires: Date.now() + 30 * 24 * 60 * 60 * 1000
        };

        // assign payload to req.user
        req.login(payload, { session: false }, error => {
          if (error) {
            res.status(400).send({ error });
          }

          // generate a signed json web token and return it in the response
          const token = jwt.sign(JSON.stringify(payload), process.env.JWT_KEY);
          const cookieOption =
            process.env.NODE_ENV === "production" ? { secure: true } : {};
          // assign jwt to cookie
          res.cookie("jwt", token, cookieOption);
          res.redirect("/");
        });
      }
    )(req, res);
  });

  app.get(
    "/api/current_user",
    passport.authenticate("jwt", { session: false }),
    (req, res) => {
      const { user } = req;
      res.status(200).send({ user });
    }
  );
};

1 Ответ

0 голосов
/ 01 мая 2020

Итак, после многих попыток я решил создать новое приложение heroku и загрузил тот же код. И это сработало! Тем не менее, я понятия не имею, что пошло не так, поскольку я никогда не редактировал buildpack et c ...

Публикуя это просто, чтобы другие подумали попробовать это раньше, чем я.

...