여권 직렬화 직렬화 해제 이해


337

Passport의 serialize 및 deserialize 방법의 워크 플로를 일반인에게 어떻게 설명 하시겠습니까?

  1. 어디로 user.id가야 passport.serializeUser합니까?

  2. 우리는 호출 passport.deserializeUser이 곳은 워크 플로우에 맞지 않는 후 괜찮아?

    // used to serialize the user for the session
    passport.serializeUser(function(user, done) {
        done(null, user.id); 
       // where is this user.id going? Are we supposed to access this anywhere?
    });
    
    // used to deserialize the user
    passport.deserializeUser(function(id, done) {
        User.findById(id, function(err, user) {
            done(err, user);
        });
    });
    

나는 아직도 내 머리를 감싸려고 노력하고 있습니다. 나는 완전한 작동하는 앱을 가지고 있으며 어떤 종류의 오류도 발생하지 않습니다.

나는 여기서 정확히 무슨 일이 일어나고 있는지 이해하고 싶습니까?

도움을 주시면 감사하겠습니다.

답변:


452
  1. 어디로 user.id가야 passport.serializeUser합니까?

사용자 ID ( done함수 의 두 번째 인수로 제공 )는 세션에 저장되고 나중에 deserializeUser함수 를 통해 전체 객체를 검색하는 데 사용됩니다 .

serializeUser세션에 저장해야 할 사용자 개체의 데이터를 결정합니다. serializeUser 메소드의 결과는로 세션에 첨부됩니다 req.session.passport.user = {}. 예를 들어, (사용자 ID를 키로 제공 할 때)req.session.passport.user = {id: 'xyz'}

  1. 우리는 호출 passport.deserializeUser이 곳은 워크 플로우에 맞지 않는 후 괜찮아?

의 첫 번째 인수 deserializeUserdone함수 에 제공된 사용자 개체의 키에 해당 합니다 (1 참조). 따라서 전체 키는 해당 키를 사용하여 검색됩니다. 여기서 해당 키는 사용자 ID입니다 (키는 사용자 개체의 모든 키, 즉 이름, 전자 메일 등일 수 있음). 에서는 deserializeUser그 키 메모리 어레이 / 데이터베이스 또는 데이터 자원과 매칭된다.

페치 된 오브젝트는 다음과 같이 요청 오브젝트에 첨부됩니다. req.user

시각적 흐름

passport.serializeUser(function(user, done) {
    done(null, user.id);
});              
                  
                 
                 └─────────────────┬──→ saved to session
                                       req.session.passport.user = {id: '..'}
                                   
                                              
passport.deserializeUser(function(id, done) {
                   ┌───────────────┘
                   
                    
    User.findById(id, function(err, user) {
        done(err, user);
    });            └──────────────→ user object attaches to the request as req.user   
});

2
그래서됩니다 user.id로 저장 req.session.passport.user되거나 user자체로 저장req.session.passport.user
Anubhav

@AB 첫 번째 매개 변수로 메소드를 deserialize하기 위해 전달 된 ID에서 사용자를 찾는 코드를 작성했습니다. 그러나 모든 요청에서 db에서 사용자를 검색합니다. 이로 인해 db의 성능이 저하됩니다. 세션에 존재하는지 여부를 확인하기 위해 역 직렬화 함수에 무엇을 작성해야합니까?
uzay95

2
@AB 나는 당신이 uzay95에 제안한 것을 이해하지 못합니다. 그래서 내 세션에는 user._id 만 있습니다. 그러나 모든 요청에 ​​대해 해당 ID를 사용하여 findUserByID 데이터베이스에서 역 직렬화하고 req.user에 넣습니다. 모든 요청에서 그러한 전화를 걸지 않으려면 어떻게해야합니까?
잔코

10
@Zanko 전체 사용자 객체를 세션 데이터에 넣을 수는 있지만 다른 부작용이있을 수 있으므로 일반적으로 좋지 않습니다. 예를 들어, 사용자가 자신의 사용자 이름을 업데이트 할 때 세션 데이터도 업데이트해야합니다. 그렇지 않으면 "깨진 이름 바꾸기 기능"으로 인해 티켓이 제공됩니다. 상대적으로 무해한 예입니다. 권한 비트 또는 동등한 민감한 데이터 (Oops ...)에서도 마찬가지입니다. 본질적으로 중복 데이터가있는 경우 항상 동일한 문제가 발생합니다. TL; DR-하지 마십시오.
최대 Truxa

1
내가 잘못 아니에요 경우, req.session.passport.user = {id: '..'}그림의 일부가 약간 꺼져 있고해야 req.session.passport.user = 785352하는 대신, 어디는 785352것입니다 user.id. 그것을 증명하기 위해 콘솔 로깅에 문제가 있지만 이해가되는 것 같습니다. 호출 할 때는 done(null, user.id);두 번째 인수 ( user.id이 경우)를 할당하는 req.session.passport.user대신 할당하는 것이 좋습니다 req.session.passport.user.id. 당신이 대신에 전달한다면 user어떨까요? req.sesssion.passport.user.id = user이해가되지 않습니다.
Adam Zerner

21

Koa 및 koa-passport를 사용하는 사람 :

serializeUser 메소드에 설정된 사용자 키 (주로 해당 사용자의 고유 ID)가 다음에 저장됨을 알고 있어야합니다.

this.session.passport.user

done(null, user)deserializeUser에서 설정 한 경우 'user'는 데이터베이스의 일부 사용자 객체입니다.

this.req.user 또는 this.passport.user

어떤 이유로 this.userdeserializeUser 메서드에서 done (null, user)을 호출 할 때 Koa 컨텍스트가 설정되지 않습니다.

따라서 app.use (passport.session ())을 호출 한 후 자신의 미들웨어를 작성하여 this.user에 넣을 수 있습니다.

app.use(function * setUserInContext (next) {
  this.user = this.req.user
  yield next
})

serializeUser 및 deserializeUser의 작동 방식이 확실하지 않은 경우 Twitter에서 확인하십시오. @yvanscher


여기서 네크로 포스트를해서 미안하지만, deserialize 설명을 읽은 후에 걱정이되었습니다. 이에 대한 질문을 여기 SO에 올렸습니다 : stackoverflow.com/questions/54154047/…
Peter Kellner

매우 유용하지만 다른 경로에서 사용자를 읽는 데 여전히 문제가 있습니다. 누구든지 나를 도울 수 있습니까? stackoverflow.com/questions/60709882/…
Harry Lincoln
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.