The frontend is http localhost and the backend is https ngrok. When I log in with OAuth in the frontend and try to call req.user in the backend, it says undefined.
Also, if both the backend and the frontend use ngrok, the same problem occurs. However, if I do not use ngrok in the backend and use the localhost which is http, everything works fine.
ngrok command: ngrok --host-header http 8000
Express: app.ts
import "~/database";
import "~/libs/passport";
import express from "express";
import session from "express-session";
import cors from "cors";
import passport from "passport";
import { router } from "~/routes";
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(session({ secret: "asdf", resave: false, saveUninitialized: false }));
app.use(cors({ origin: true, credentials: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use("/", router);
app.listen(8000, () => {
console.log("Server has been started...");
});
React: App.tsx
import React, { useCallback, useEffect } from "react";
import logo from "./logo.svg";
import "./App.css";
function App() {
const handleSignIn = useCallback(() => {
window.location.assign("http://localhost:8000/api/auth");
}, []);
useEffect(() => {
const process = async () => {
const result = await fetch("http://localhost:8000/api/profile", {
credentials: "include",
});
console.log(await result.json());
};
process();
}, []);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<button onClick={handleSignIn}>DASD</button>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
There's no error, but req.user is undefined.
/api/auth
api.get("/", passport.authenticate("github", { scope: ["repo"] }));
/api/auth/callback
api.get(
"/",
passport.authenticate("github", {
failureRedirect: failureURL,
successRedirect: frontendOrigin,
})
);
Add: and call /api/profile in frontend, status is 401.
/api/profile
api.get("/", async (req, res) => {
if (!req.isAuthenticated()) {
return res.status(401).json();
}
const profile: Profile = {
username: req.user.username,
name: req.user.name,
avatarURL: req.user.avatarURL,
};
return res.status(200).json(profile);
});
CodePudding user response:
Apparently you can't
CORS with HTTP Basic Authentication
ngrok's HTTP tunnels will work with CORS, but you cannot use ngrok's --basic-auth option. ngrok's HTTP tunnels allow you to specify basic authentication credentials to protect your tunnels. However, ngrok enforces this policy on all requests, including the preflight OPTIONS requests that are required by the CORS spec. In this case, your application must implement its own basic authentication.
It might be because you yuse credentials: true
, ngrok already uses --basic-auth
option.
Can you share the error thrown ?