尝试获取资源 Passport ReactJS 和 ExpressJS 时出现 NetworkError:CORS

Posted

技术标签:

【中文标题】尝试获取资源 Passport ReactJS 和 ExpressJS 时出现 NetworkError:CORS【英文标题】:NetworkError when attempting to fetch resource Passport ReactJS and ExpressJS : CORS 【发布时间】:2021-01-10 10:51:35 【问题描述】:

我有一个使用 React JS (http://localhost:3000/) 开发的前端和使用 express JS (http://localhost:5000/) 开发的后端

谷歌控制台详情

React 登录页面:点击使用 Google 登录

  const _handleGoogleSignInClick = async () => 
        window.open("http://localhost:5000/socialauth/google", "_self");
    

快递代码

app.use(express.json());
app.use(cookieSession(
    name: "session",
    maxAge: 24 * 60 * 60 * 1000,
    keys:[keys.session.cookieKey]
))

app.use(cookieParser());
app.use(passport.initialize());
app.use(passport.session());
app.use(
    cors(
      origin: "http://localhost:3000",
      methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
      credentials: true
    )
  );

//routes
app.use(cors());
app.use("/auth", require("./routes/jwtAuth"));
app.use("/socialauth", socialAuth);

********************************************************
const CLIENT_HOME_PAGE_URL = "http://localhost:3000";

router.get('/google', passport.authenticate('google',  scope: ["profile"] ));
router.get('/google/callback', passport.authenticate('google', 
    successRedirect: CLIENT_HOME_PAGE_URL,
    failureRedirect: "/socialauth/login/failed"
));

router.get("/login/success", (req, res) => 
    console.log(req.user);
    if (req.user) 
        res.json( true);
    
);

现在我已经成功地验证了来自 Google 的用户,passport JS 为用户创建了一个会话,并将用户重定向到前端,他们必须再次验证自己。此时前端尝试验证用户,服务器验证用户成功并返回true,但这并没有被前端捕获。因此,用户无法看到仪表板,因为状态保持为假...

fetch("http://localhost:5000/socialauth/login/success", 
          method: "GET",
          credentials: "include",
          headers: 
            Accept: "application/json",
            "Content-Type": "application/json",
            "Access-Control-Allow-Credentials": true
          
        )
          .then(response => 
            if (response.status === 200) return response.json();
            throw new Error("failed to authenticate user");
          )
          .then(responseJson => 
            console.log("responseJson is -====", responseJson);
            setIsAuthenticated(true);

问题?

在从客户端访问 fetch("http://localhost:5000/socialauth/login/success" 时,我看到服务器可以成功识别用户并返回 true,但是在我的客户端我无法获取 JSON 响应。

错误详情

错误是 -==== TypeError: NetworkError 尝试获取资源时。桌面组件.js:62 跨域请求被阻止:同源策略不允许在“http://localhost:5000/socialauth/login/success”读取远程资源。 (原因:如果 CORS 标头“Access-Control-Allow-Origin”为“*”,则不支持凭据)

【问题讨论】:

【参考方案1】:

编辑:问题是 app.use(cors()) 覆盖

app.use(
    cors(
      origin: "http://localhost:3000",
      methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
      credentials: true
    )
  )

在将 CORS 与凭据一起使用时这是必需的

可以参考CORS credentials

这基本上是因为您的客户端正在发送带有 withCredentials 的请求,您需要将其设置为 false(或者更改服务器端的 Access-Control-Allow-Origin

【讨论】:

如果 front end = withCredentials 设置为 false,服务器无法识别用户。 我不熟悉您的环境以及是否存在来自 Google 配置的限制,但还有其他方法可以识别用户。您将需要更改您的 Access-Control-Allow-Origin,它不能是 *:您需要指定协议 + 域 + 端口。例如:``` var cors = require('cors'); app.use(cors(credentials: true, origin: 'localhost:3000')); ``` 我已经做到了这一点,你可以在上面的快速代码中看到。 .但还是失败了。 天啊。那是罪魁祸首......它工作的人......尝试编辑您的评论。让我为你投票。非常感谢。我忘了删除 app.use(cors())。

以上是关于尝试获取资源 Passport ReactJS 和 ExpressJS 时出现 NetworkError:CORS的主要内容,如果未能解决你的问题,请参考以下文章

React JS:尝试获取资源时导致 NetworkError 的 CORS 错误

如何使用分离的后端和前端(Passport / Express / React)进行社交身份验证

Laravel Passport尝试获取非对象的属性“秘密”

Laravel7 Passport:尝试将请求发送到“api/user”时获取“未定义索引:aud”

Express + Passport + CORS:允许多个域的会话

前面读取来自nodejs的cookie(Reactjs)