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!