Привет, поэтому я пытаюсь использовать express-session
и connect-mongodb-session
, TypeScript Express/Node Api, теперь я хочу сделать, когда пользователь войдет в систему, я буду использовать экспресс-сеанс для создания этого файла cookie, и этот файл cookie автоматически сохраняется в MongoDB. Теперь проблема, с которой я сталкиваюсь, заключается в том, что я хочу добавить детали к этому сеансу, т.е. информацию о пользователе, чтобы при сохранении пользователя я знал его имя пользователя и т. д.
Теперь, когда я не использую TypeScript, я могу просто сделать что-то подобное, чтобы добавить информацию о пользователе в создаваемый сеанс:request.session.user = {username:'John', id='97y9797977c9q7dw7y9qw7d9721'}
Но теперь при использовании TypeScript я получаю следующую ошибку, когда пытаюсь сделать то же самое, что и выше:\
Код ниже: это моя настройка для express-session
и connect-mongodb-session
const store = MongoStore(expressSession);
const mongoURI = process.env.mongoURI;
const mongoStore = new store({
collection: 'usersessions',
uri: mongoURI,
expires: 10 * 60 * 60 * 24 * 1000
});
app.use(
expressSession({
name: '_sid',
secret: process.env.session_secret,
resave: false,
saveUninitialized: false,
store: mongoStore,
cookie: {
httpOnly: true,
maxAge: 10 * 60 * 60 * 24 * 1000,
secure: process.env.NODE_ENV === 'production'
}
})
);
Ниже приведен код моего контроллера метода SignIn.
SignIn(request: Request, response: Response) {
const form = new Formidable.IncomingForm();
try {
form.parse(request, async (error, fields, files) => {
if (error) {
return response.status(500).json({
msg: 'Network Error: Please try again later'
});
}
const { username, password } = fields;
if (!username || !password) {
return response.status(400).json({ msg: 'All fields are required' });
}
const user: any = await userModel.findOne({
usernam: username
});
if (!user) {
return response.status(404).json({
msg: 'Account with this username does not exist'
});
}
const hashedPassword = user.password;
const isPasswordValid = await Bcrypt.compare(password, hashedPassword);
if (!isPasswordValid) {
return response.status(400).json({ msg: 'Invalid credentials' });
}
const isUserSessionExisting = await userSession.findOne({
'session.user.username': username
});
if (isUserSessionExisting) {
return response
.status(200)
.json({ msg: 'Account already logged in' });
}
const userSessionObj = {
username: user.username,
id: user._id
};
request.session.user = userSessionObj; //This is where the error is coming
return response.status(200).send(request.sessionID);
});
} catch (error) {
return response
.status(500)
.json({ msg: 'Network Error: Please try again later' });
}
}
Как я могу решить эту проблему
Большое спасибо, только что попробовал, и это работает, большое спасибо
у вас есть 2 способа объявить сеанс.
import {Request} from "express"
type Req= Request & { session: Express.Session }; // this will be merges
или
declare global {
namespace Express {
interface Request {
// currentUser might not be defined if it is not logged in
session: Express.Session;
}
}
}
и это интерфейс сеанса:
interface Session extends SessionData {
id: string;
regenerate(callback: (err: any) => void): void;
destroy(callback: (err: any) => void): void;
reload(callback: (err: any) => void): void;
save(callback: (err: any) => void): void;
touch(): void;
cookie: SessionCookie;
}
как видите, пользовательского свойства нет. Потому что обычно мы сохраняем уникальный идентификатор в файле cookie, который является идентификатором базы данных. Поскольку имя пользователя может быть изменено в будущем, но идентификатор базы данных пользователя или если вы выполняете аутентификацию Google oauth, идентификатор пользователя Google не меняется. Сохранения идентификатора было бы достаточно. Но если вы все еще хотите прикрепить пользовательский объект к сеансу, создайте новый пользовательский интерфейс
interface User{
username: string;
id:string
}
type NewSession=Express.Session & User
declare global {
namespace Express {
interface Request {
// currentUser might not be defined if it is not logged in
session: NewSession;
}
}
}
Лучший подход может быть
const { session }: { session: Session & Partial<YourCustomType> } = request;
вы можете попробовать импортировать {Session} из «express-session»; объявить модуль 'экспресс-сеанс' { интерфейс сеанса { пользователь: пользователь; } }