I'm new to working with Express and I'm currently developing an authentication feature using email and password.
The authentication process is complete, but now I'm looking to secure the API routes based on user roles.
Once authenticated, when I use console.log(req.user)
, I can see the user properties listed below.
{
firstName: 'test',
lastName: 'test',
email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f084958384b09588919d809c95de939f9d">[email protected]</a>',
password: 'password',
role: 'user',
createdAt: '2022-08-31T05:46:07.573Z',
updatedAt: '2022-08-31T05:46:07.573Z'
}
However, when I attempt conditional branching with req.user.role
, I receive an error indicating that it's undefined.
Property 'role' does not exist on type 'User'.ts(2339)
The same issue occurs if I try to access the property as 'req.user.attributes.role', resulting in it being undefined.
In addition, there's an error in the "passport.deserializeUser" section when using the following URL method.
More details here
Argument of type 'User' is not assignable to parameter of type 'false | User | null | undefined'.
Type 'import("/Users/takeshi/FanFundBackEnd/db/entity/user").default' is not assignable to type 'Express.User'.
Types of property 'role' are incompatible.
Type 'import("/Users/takeshi/FanFundBackEnd/db/entity/user").UserRole | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.ts(2345)
Any suggestions on how to properly access the property of req.user?
isAdmin.ts => If the user type is 'user', return HTTP status 401.
export const isAdmin = (req: Request, res: Response, next: NextFunction) => {
if (req.user.role != 'user') {
// Error: Property 'role' does not exist on type 'User'.ts(2339)
console.log('Check User type is not user')
next();
}
res.status(401).json({ "message": "Unauthorized, Check Your User Type" });
};
passportjs
const local = new Strategy({
usernameField: 'email',
passwordField: 'password'
}, async (email, password, done) => {
try {
const user = await UserController.getUser(email);
if (!user) {
console.log("unknown User")
return done(null, false, { message: 'Unknown User' });
}
const c = user.password!;
if (await bcrypt.compare(password, c.toString())){
return done(null, user);
} else {
console.log("invalid password")
return done(null, false, { message: 'Invalid password' });
}
} catch (error) {
return done(error, null);
}
});
passport.serializeUser((user, done) => {
console.log('serialize', user);
done(null, user);
});
passport.deserializeUser(async (user: User, done) => {
console.log('deserialize');
if (user) {
done(null, user);
} else {
throw new Error('User does not exist');
}
});
passport.use(local);