Экспресс-сессия: как добавить информацию о пользователе в экспресс-сессию TypesScript

Привет, поэтому я пытаюсь использовать 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' });
    }
  }

Как я могу решить эту проблему

вы можете попробовать импортировать {Session} из «express-session»; объявить модуль 'экспресс-сеанс' { интерфейс сеанса { пользователь: пользователь; } }

ABOS 11.12.2020 16:41

Большое спасибо, только что попробовал, и это работает, большое спасибо

Ntshembo Hlongwane 11.12.2020 16:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
1 845
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

у вас есть 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;

Другие вопросы по теме