通过Passport.js与React上的第三方(discord)进行身份验证,在本地可以工作,但在Heroku上托管时就不行了。

问题描述 投票:0回答:1

我一直在尝试用Passportjs实现与discord的登录,并设法让它在本地工作(部分原因是我在处理回调后的重定向时遇到了问题,所以目前我手动将自己路由回登陆页面@""),成功重定向至 https:/discordapp.comoauth2authorize。...和所有。然而,当在Heroku上托管时,它不再工作,地址栏显示正确的 "authdiscord "地址,但只显示一个空白页。

我试过使用react-router-bootstrap中的LinkContainers,使用react-bootstrap中的Nav.Item和Nav.Link,打开和关闭CORS,重新安排服务器端路由顺序,只使用锚点标签,调整认证请求的范围以及其他一些我现在想不起来的东西。不过似乎没有什么不同。我一定是搞错了方向。

如果有任何关于我应该注意什么的提示,我将非常感激。请在下面找到我的代码。

App.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);

authRoutes.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 });
    }
  );
};
reactjs express heroku passport.js
1个回答
0
投票

所以,在尝试了很多东西之后,我决定创建一个新的heroku应用,并上传了同样的代码。它的工作! 但还是不知道哪里出了问题,因为我从来没有编辑过buildpack等......

发这个帖子只是为了让其他人比我更早地想到要尝试这个。

© www.soinside.com 2019 - 2024. All rights reserved.