koa-passport w/ passport-steam: ctx.isAuthenticated() 总是假的

koa-passport w/ passport-steam: ctx.isAuthenticated() always false

我正在使用 koa-passport 和 passport-steam 来使用 SteamID 验证用户。 ctx.isAuthenticated() 始终为假,尽管通过 Steam 正确登录。我一直在查看大量其他 SO 问题和指南以及 google 结果,这个问题很常见,但总是由于某些不适用于我的代码的特殊错误。显然还有一些其他特殊问题困扰着我的代码,但我找不到它。 大多数与护照相关的代码实际上是从 tutorials/docs/examples 复制粘贴的。我的中间件顺序正确,据我所知这不是会话配置问题。

const Koa = require("koa");
const session = require("koa-session");
const Router = require("@koa/router");
const views = require("koa-views");
const passport = require("koa-passport");
const SteamStrategy = require("passport-steam").Strategy;
const bodyparser = require("koa-bodyparser");

const root = "http://localhost:3000";
const app = new Koa();
const router = new Router();

passport.serializeUser((user, done) => {
    console.log("Serializing:", user);
  done(null, user);
});

passport.deserializeUser((obj, done) => {
    console.log("Deserializing:", obj);
  done(null, obj);
});

passport.use("steam", new SteamStrategy({
        returnURL: root + "/auth/steam/return",
        realm: root,
        apiKey: "---"
    },
    function(identifier, profile, done) {
        process.nextTick(function () {
            let identifie = identifier.match(/\/id\/(\d+)/)[1];
            profile.id = identifie
            console.log("Returned from Steam:", profile);
            return done(null, profile);
        });
    })
);

app.on("ready", () => {
    console.log('ready');
});

app.on("error", (err, ctx) => {
    console.log("ERR:", err);
});

const CONFIG = {
    key: 'koa.sess',
    maxAge: 10000,
    secure: true
} 
//I have tried tons of cookie settings including using default
//because a lot of people in the koa-passport issues seem to have solved
//their similar problem by changing session settings, but I've had no such luck
app.keys = ['session_secret'];
app.use(session(CONFIG, app));
app.use(bodyparser());
app.use(passport.initialize());
app.use(passport.session());

app.use(views("views", { 
            map: { 
                ejs: "ejs" 
            }
        })
);

//A shoddy attempt at middleware just to test. But ctx.isAuthenticated always returns false.
app.use(async (ctx, next) => {
    if (ctx.isAuthenticated()) {
        console.log("Hey! You're authenticated");
    }
    return next()
});

app.use(router.routes());


router.get("/", async (ctx, next) => {
    await ctx.render("howdy.ejs");
});

router.get("/auth/steam", async (ctx, next) => {
    console.log("Trying to auth");  
    return passport.authenticate('steam', { failureRedirect: "/fail" })(ctx);
});

router.get("/auth/steam/return", async (ctx, next) => {
    passport.authenticate('steam', { failureRedirect: "/fail", successRedirect: "/text" })(ctx);
    ctx.redirect("/text");
});

router.get("/fail", async (ctx, next) => {
    await ctx.render("fail.ejs");
});

router.get("/text", async (ctx, next) => {
    console.log(`
    Auth: ${ctx.isAuthenticated()},
    Unauth: ${ctx.isUnauthenticated()},
    User:
    `);
    console.log(ctx.state.user);
    console.log(ctx.req.user);
    if (ctx.state.user) {
        await ctx.render("success.ejs");
    } else {
        await ctx.render("fail.ejs");
    }
});


app.listen(3000);

让我们来看一个交互示例: 您单击索引上的按钮将您带到 /auth/steam。 Trying to auth 在(我的)控制台中打印,您将被重定向到 Steam。您登录(登录后您将被重定向到 /text)。

Trying to auth
   
    Auth: false,
    Unauth: true,
    User:
    
undefined //ctx.state.user, this is how koa-passport should expose the authenticated user.
undefined //ctx.req.user, as a test. I don't expect it to be defined but I see it mentioned in some docs.
Returned from Steam: {YOUR PROFILE!}
Serializing: {YOUR PROFILE!}

我的测试打印信息显示 Auth/Unauth/User 打印在配置文件之前,我认为这是因为某种异步竞赛。 可以肯定的是,您将重新加载页面 (/text) 以再次获取此类信息:

    Auth: false,
    Unauth: true,
    User:
    
undefined
undefined

没有变化!

你现在可能已经离开了这个,但你的问题给了我在我的项目中获得 Steam 身份验证所需的东西,所以我想我应该分享我的发现。

我没有直接 运行 你的代码示例,但我认为这是两个问题。

首先,您的 /auth/steam/return 端点需要更新。它应该是这样的:

router.get("/auth/steam/return", async (ctx, next) => {
    return passport.authenticate('steam', { failureRedirect: "/fail", successRedirect: "/text" })(ctx);
});

其次,我在会话配置方面遇到了问题。具体来说 secure: true 对我不起作用,因为我正在通过不安全的连接 (http) 进行测试。本地主机可能有例外,但如果没有,更改 CONFIG 对我有用。我还更改了 maxAge,因为它被设置为 10 秒或 10,000 毫秒。

const CONFIG = {
    key: 'koa.sess',
    maxAge: 86400000,
    secure: false
}