我一直在尝试用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 });
}
);
};
所以,在尝试了很多东西之后,我决定创建一个新的heroku应用,并上传了同样的代码。它的工作! 但还是不知道哪里出了问题,因为我从来没有编辑过buildpack等......
发这个帖子只是为了让其他人比我更早地想到要尝试这个。