카테고리 없음

[node.js] Express cookieSession 및 Mongoose : request.session.user를 Mongoose 모델로 만들려면 어떻게해야합니까?

행복을전해요 2021. 1. 21. 23:05

Express 세션은 별도의 저장소로 저장되며 여기에 저장할 수있는 항목에 제한이 있습니다. 프로토 타입 데이터 (메소드)를 저장할 수 없습니다. 좀 더 key<>value스토리지 처럼 보아라 .

그 이유는 세션이 다음과 같이 어디에나 (거의) 저장 될 수 있기 때문입니다. 프로세스 메모리; 데이터베이스 (mongodb); redis; 기타

이 때문에 세션 객체에 무엇이든 넣고 요청이 완료되면 express는 세션 데이터를 가져 와서 파싱하고 순수한 객체처럼 세션 저장소에 고정합니다. 기본적으로 프로세스 메모리이지만 앞서 언급했듯이 다른 저장소가 될 수 있습니다.

따라서 다음 http 요청이 발생하면 세션 미들웨어는 요청 헤더의 쿠키 (사용되는 경우) 데이터를 사용하여 세션 복원을 시도하고 세션 저장소에 데이터를 다시 제공하도록 요청합니다. 이미 포맷으로 - 그것은 .prototype 물건하지만 단지 데이터 (가 없습니다 object, array, string, number, 등 간단한 물건을).

따라서 해당 데이터에서 모델을 다시 만들어야합니다.
Express에서 미들웨어로 할 수 있습니다. 따라서 app.configure정의 직후에 session 다음을 수행 할 수 있습니다.

app.use(function(req, res, next) {
      if (req.session && req.session.user) {
          req.session.user = new UserModel(req.session.user);
            }
              return next();
              });
              

세션이 사용자와 함께 정의되어 있는지 확인합니다. 그런 다음 해당 데이터에서 몽구스 모델을 다시 만듭니다.

여기 주석에서 언급했듯이-데이터 소유권에 대한 책임 분할로 인해 불일치가 발생할 수 있으므로 세션에 사용자 데이터를 저장해서는 안됩니다. 따라서 ID사용자 만 저장 한 다음 미들웨어를 사용하여 데이터베이스에서로드합니다.

app.use(function(req, res, next) {
  if (req.session && req.session.userID) {
      UserModel.findById(req.session.userID, function(err, user) {
            if (!err && user) {
                    req.user = user;
                            next();
                                  } else {
                                          next(new Error('Could not restore User from Session.'));
                                                }
                                                    });
                                                      } else {
                                                          next();
                                                            }
                                                            });
                                                            

미들웨어를 생성하여 사용자가 로그인했는지 확인할 수 있습니다.

function userRequired(req, res, next) {
  if (req.user) {
      next();
        } else {
            next(new Error('Not Logged In');
              }
              }
              

그리고 다음과 같이 사용하십시오.

app.get('/items', userRequired, function(req, res, next) {
  // will only come here if user is logged in (req.user !== undefined)
  });
  
-------------------

작동하더라도 (Maksims의 상세한 이유 때문에 작동하지 않음) 세션에서 사용자 모델 인스턴스를 유지하는 것은 좋지 않습니다. 동일한 사용자가 두 번 이상 로그인하면 두 세션의 사용자 인스턴스가 동기화되지 않고 서로를 계속 덮어 씁니다.

이를 수행하는 올바른 방법 _id은 세션 (예 :)에서 사용자 를 유지하고 request.session.userIdExpress 미들웨어를 설치하여 사용자 모델 인스턴스를로드 request.user하여 다른 미들웨어 및 현재 호출에 대한 라우트 핸들러에서 사용할 수 있도록하는 것입니다. 지금하고있는 것과 비슷하지만 조금 더 깨끗합니다.

단일 객체를 찾는 _id것은 엄청나게 빠르며 자주 수행하기 때문에 이미 메모리에 있으므로 오버 헤드가 없습니다.

-------------------

전체 사용자 객체를 보유하기 위해 세션 저장소에 의존하는 복잡성 문제에도 불구하고 메서드를 사용하여 일반 JS 객체에서 몽구스 객체를 초기화 수 있습니다init() (이 글을 쓰는 시점에서 v4.4.14).

req.user = new UserModel().init(req.session.user);
req.user.name = 'James';
req.user.save( ... );

다음 과 같지 않음 ( 업데이트하지 않고 동일한 문서 를 저장하려고합니다 _id) :

req.session.user = new UserModel(req.session.user);
req.user.name = 'James';
req.user.save( ... );


출처
https://stackoverflow.com/questions/22009798