You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Node.js集成Steam登录遇InternalOpenIDError问题求助

问题:Steam OpenID登录验证失败(InternalOpenIDError)

我正在为网站实现Steam账号登录功能,Google登录配置很顺利,但OpenID相关配置不直观。React前端运行在localhost:3000,Node.js API运行在localhost:3010。点击UI登录按钮后能跳转到Steam授权页面,但完成授权后出现InternalOpenIDError: Failed to verify assertion错误,尝试多种配置仍无法解决,以下是我的API代码:

require("dotenv").config();
const express = require("express");
const app = express();
const cors = require("cors");
const PORT = process.env.PORT || 3010;
const router = require("./routes/router");
const db = require("./models/index");
const http = require("http").createServer(app);
router.use(express.json());
const corsOptions = {
  origin: ["http://localhost:3000", "https://gangs.gg"], // http://localhost:3000 for electron, otherwise deployed ui
  methods: "GET,POST",
  allowedHeaders: "Content-Type,Authorization",
};
app.use(cors(corsOptions), router);
app.use(require("prerender-node").set("prerenderToken", "pmAz691dTZfZ6GTrUiZZ"));
const path = require("path");
const { main } = require("./startup/startup");
const messageController = require("./controllers/message-controller");
//Steam
const passport = require("passport");
const SteamStrategy = require("passport-steam").Strategy;
const session = require("express-session");

//START STEAM
app.use(
  session({
    secret: process.env.SESSION_SECRET,
    name: process.env.SESSION_NAME,
    resave: true,
    saveUninitialized: true,
  })
);
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser((user, done) => {
  done(null, user);
});
passport.deserializeUser((obj, done) => {
  done(null, obj);
});
passport.use(
  new SteamStrategy(
    {
      returnURL:
        process.env.IS_PROD === "1" ? "https://www.gangs.gg/steam/return" : "http://localhost:3010/steam/return",
      realm: process.env.IS_PROD === "1" ? "https://www.gangs.gg" : "http://localhost:3000",
      apiKey: process.env.STEAM_API_KEY,
    },
    (identifier, profile, done) => {
      profile.identifier = identifier;
      done(null, profile);
    }
  )
);
//STEAM ROUTES
const redirectUrl = process.env.IS_PROD === "1" ? "https://www.gangs.gg/login" : "http://localhost:3000/login";

app.get("/steam", passport.authenticate("steam", { successRedirect: "/", failureRedirect: "/" }), function (req, res) {
  console.log("authenticating!! ", res);
  res.redirect("/");
});

// GET /auth/steam/return
//   Use passport.authenticate() as route middleware to authenticate the
//   request.  If authentication fails, the user will be redirected back to the
//   login page.  Otherwise, the primary route function function will be called,
//   which, in this example, will redirect the user to the home page.
app.get(
  "/steam/return",
  passport.authenticate("steam", { failureRedirect: redirectUrl }),
  // function (req, res, next) {
  //   req.url = req.originalUrl;
  //   next();
  // },
  function (req, res) {
    console.log("authenticatedddd!! ", res);
    res.redirect("/");
  }
);

解决方案

1. 修正Realm配置(核心问题)

Steam的realm参数必须与returnURL属于同一域名/端口。你当前本地环境的realm设为前端地址http://localhost:3000,但returnURL是API地址http://localhost:3010/steam/return,两者端口不一致,导致验证失败。

修改SteamStrategy的realm配置:

realm: process.env.IS_PROD === "1" ? "https://www.gangs.gg" : "http://localhost:3010",

2. 优化Session配置

确保session能正确保存验证状态,调整配置符合最佳实践:

app.use(
  session({
    secret: process.env.SESSION_SECRET,
    name: process.env.SESSION_NAME,
    resave: false, // 避免不必要的session重写
    saveUninitialized: false, // 不保存未初始化的session
    cookie: {
      secure: process.env.IS_PROD === "1", // 生产环境启用HTTPS Cookie,本地禁用
      sameSite: "lax", // 缓解跨域Cookie限制
      maxAge: 24 * 60 * 60 * 1000 // 设置session有效期为1天
    }
  })
);

3. 验证Steam API Key有效性

确认.env中的STEAM_API_KEY是正确的,且已在Steam开发者后台完成注册(生产环境需将returnURL添加到Steam后台的回调地址列表中)。

4. 本地环境注意事项

Steam不支持本地HTTPS回调地址,确保本地开发全程使用http协议,不要强制跳转HTTPS。

内容的提问来源于stack exchange,提问作者Dalton Klein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 03:27:52