0

I can't for the life of me figure this one out :(

Problem

My app is a game, so the users are called players. In order to keep consistency across the app, I want to change the property name that koa-passport uses when it logs a user in. The default is user, but I want it to be player

Setup

My app is set up like this:

import Koa from "koa";
import session from "koa-session";
import passport from "koa-passport";
const sessionConfig = {
    // setting same site to combat csrf
    sameSite: "strict",
};
// SESSION_SECRET is stored as a stringified array, so needs to be parsed
const secret = JSON.parse(process.env.SESSION_SECRET.replaceAll("\\", ""));
export const app = new Koa();
app.keys = secret;
app.use(session(sessionConfig, app));
app.use(passport.initialize());
app.use(passport.session());

I'm serialising and deserialising users like this:

passport.serializeUser((player, done) => {
    done(null, player.username);
});

passport.deserializeUser(async (username, done) => {
    try {
        const player = await Player.findOne({ username: username }).exec();
        done(null, player);
    } catch (error) {
        done(error);
    }
});

I'm using the local strategy for now. It looks like this:

export const local = new LocalStrategy(async (username, password, done) => {
    try {
        // need to include the password here explicitly because it
        // isn't included automatically in queries
        let player = await Player.findOne(
            { username: username },
            "+password"
        ).exec();
        if (!player) return done(null, false);
        const match = await player.validatePassword(password);
        player = stripPassword(player);

        if (match) {
            done(null, player);
        } else {
            done(null, false);
        }
    } catch (error) {
        return done(error);
    }
});

It's added to the passport instance like this: passport.use(local);

Here's my login route:

import Router from "@koa/router";
import { passport } from "./setup.js";

export const auth = new Router();

auth.post("/login", async (ctx, next) => {
    await passport.authenticate(
        "local",
        async (err, player, info) => {
            if (err) throw err;
            ctx.body = { player, info };
            await ctx.login(player);
        }
    )(ctx, next);
});

Result

With the current setup, users are getting logged in, and the state and session looks like this:

ctx.session :>>  { passport: { user: 'test' } }
ctx.state :>>  {
  _passport: {
    instance: Authenticator {
      _key: 'passport',
      _strategies: [Object],
      _serializers: [Array],
      _deserializers: [Array],
      _infoTransformers: [],
      _framework: [Object],
      _sm: [SessionManager],
      Authenticator: [Function: Authenticator],
      Passport: [Function: Authenticator],
      Strategy: [Function],
      strategies: [Object],
      KoaPassport: [class KoaPassport extends Authenticator],
      _userProperty: 'user'
    }
  },
  user: {
    _id: new ObjectId("6403596f3cd309811b41d135"),
    username: 'test',
    joined: 2023-03-04T14:45:03.199Z,
    __v: 0
  }
}

Attempts

Here's what I've attempted in order to change the user property, all with zero success:

  • app.use(passport.initialize({ userProperty: 'player' }));
  • await passport.authenticate('local', { customProperty: 'player' }, async (err, player, info) => {...});
  • await passport.authenticate('local', { userProperty: 'player' }, async (err, player, info) => {...});
  • export const local = new LocalStrategy({ userProperty: 'player' }, async (username, password, done) => {});
  • await ctx.login(user, { userProperty: 'player' });
  • passport._userProperty = 'player';

In every case, the property stays as user

Note: koa-session stores its data in a cookie by default. I have cleared cookies between each attempt in case some data persisted there might cause issues, but still no joy

This seems like it should be a really simple thing to do, any help would be much appreciated!

0 Answers0