• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

질문이요.

19.07.31 05:18 작성 조회수 228

0

////////////////////////////////////////////////////////

강의를 여러번 다시보고 질문좀 남겨요... 

 

npm start를 하면, 

app.js 에서 

연결된 모든 const  000 = requires('./000') or requires('0000') 들이 시작되고나서, 

 

모든 미들웨어 들이 위에서부터 시작하잖아요. 

여기에서 의문점은요, 이 경우에 

app.use(passport.initialize());

app.use(passport.session());

app.get('/', indexRouter) 

 

app.use(passport.session()); 가 passport.deserializeUser를 실행 시킨다고 하셧잖아요. 

그래서 이런 식으로 console.log를 넣어 봤습니다. 

passport.deserializeUser((id, done) => {
console.log("안녕 나 실행.")
...........
}

 

인제 npm start를 하고 메인 페이지를 돌려 봤습니다.

순서상으로, app.get('/', indexRouter) 가 app.use(passport.session()); 보다 뒤 인데, 

콘솔 로그에는 "안녕 나 실행." 이 찍히지 않았습니다. 

이 뜻은, serializeUser가 된 상태에서만, deserializeUSer 가 작동 된다는 사실인가요? 

미들웨어인

app.use(passport.initialize());

app.use(passport.session());

가 있어도, 그냥 작동만하고 next()처럼 넘어가는 형식인가요?

로그인을 하지 않는 이상 찍히지 않네요.

로그인을 해서 serializeUser 상태에서만 deserializeUSer이  가능한뜻인가요..?  

그러면 로그인을 누름과 동시에 serializeUser에 저장이되고, app.use(passport.session());에서 걸려서, 

passport.session()은 passport.deserializeUser를 불러서, passport.deserializeUser는 id와 done을 콜백함수로 넘겨주는 건가요?? 

 

////////////////////////////////////////////////////////

로그인시, 

join.pug 에서 

extends layout

block content
.timeline
form#join-form(action='/auth/join' method='post')
.input-group
label(for='join-email') 이메일
input#join-email(type='email' name='email')
.input-group
label(for='join-nick') 닉네임
input#join-nick(type='text' name='nick')
.input-group
label(for='join-password') 비밀번호
input#join-password(type='password' name='password')
if joinError
.error-message= joinError
button#join-btn.btn(type='submit') 회원가입

 

에서 name 그대로 email 과 password를 넘어 오잖아요. 

로그인 버튼을 클릭시, app.js 에서, 

....
app.use(express.urlencoded({extended : false }));
 
 
app.use('/auth', authRouter);
...
 

 

app.use(express.urlencoded({estended : false}));

프론트에서 받은 email 과 password를 읽어오고난후,

app.use('/auth', authRouter);

에 걸려서, 

auth.js로가서 

router.post('/login',isNotLoggedIn,(req,res,next)=>{ //req.body.email req.body.password
passport.authenticate('local',(authError,user,info)=>{
.....
return res.redirect('/');
});
})(req,res,next);
});

 

 

router.post('/login',isNotLoggedIn,(req,res,next)=>

여기에서의 req.body.email 과 req.body.password로 접근 가능, app.use(express.urlencoded({estended : false}));

에서 읽어 왔기 때문에. 

passport.authenticate('local'

 이것이 실행되면, localStrategy.js 를 불러서,


passport.use(new LocalStrategy({
usernameField: 'email', // req.body.email join.pug 에서 넘어옴.
passwordField: 'password', //req.body.password
}, async(email, password, done) =>{
...
done(null, exUser);
 
}

 

usernameField: 'email'

passwordField: 'password'

궁금한게,  'email' 'password' 만 으로 접근이 가능한 이유에요. 

지금 이게 join.pug의 것인데, email 와 password name 그대로 써준것 뿐인데 바로 넘어와서 쓸 수 있는게 잘 이해가 안가네요/? 

왜 req.body.email 과 req.body.password 이런식으로 접근을 안하나요??? 

 

그리고 email, password, done 의 async 인자들은 갑자기 어디서 나온건지가 잘이해가 안가네요 ?? 

new LocalStrategy (...)

에서 email, password, done 의 async 콜백 인자를 넘겨 준건가요??? 

그리고 async쓰신 이유좀 알려주실수있나요?? 

 

모든게 잘 작동하면(비밀번호가 비크립으로 잘 맞고이러면), 

done(null, exUser);

를 하고나서, 다시 

passport.authenticate('local',(authError,user,info)=>{
....
return req.logIn(user,(loginError)=>{
....
return res.redirect('/');
});
})(req,res,next);
});

 

여기에서 done() 에서 콜백으로  인자를 넘겨주잖아요.

(authError,user,info)=>{

 

done() 은 어떤식으로 짜여있나요..? 

실패 성공 여부와 실패시 메세지 넘기는 용도로만 사용하나요? 

req.logIn(user,

인제 여기서 드디어, serializeUser를 해주잖아요. 

 

passport.serializeUser((user, done) => {
// {id:1, name:zero, age:25} -> 1
done(null, user.id); // 사용자 정보를 모두 세션에 저장하기 무거워서 아이디만 저장.

});

 

done(null, user.id);

여기서 세션에 저장을 시키는 건가요? 

done(null,user.id) 면 user.id를 인자로 넘기는거 아닌가요?????? 

done(null,user.id) 넘어 와서(성공시), 

return res.redirect('/');

 

이렇게 리다이렉이 되고, app.js가 다시 실행되고 나서, 

app.use(passport.initialize());

app.use(passport.session());

여기에서, 

app.use(passport.session()); 이 deserializeUser

를 실행시키고, 

passport.deserializeUser((id, done) => {
console.log("안녕 나 실행.")
// 1 로 찾고-> {id:1, name:zero, age:25} 찾은후 -> req.user 저장
if(user[id]){
done(user[id]);
}else{
User.findOne({ where: { id } })
.then(user => done(null, user))
.catch(err => done(err));
}
 
});

serializeUser로 저장된 user.id 가 passport.session()에 의해서 인자가 전달되는건가요 ?

then(user => done(null, user))

이 뜻 잘이해가 안가네요?? 이게 done(null,user)로 넘긴다는건가요 ? 넘긴다면 어디로 콜백을 넘기나요?? 

 

app.js에서 

 app.get('/', indexRouter) 이렇게 되잖아요. 

page.js 에 이것에 걸리고

router.get('/', (req, res, next) => {
res.render('main', { // main.pug 렌더링
title: 'NodeBird', // main.pug에 있는 변수들
twits: [],
user: req.user, // 즉 done에서 성공시 in localStoragy 세션에 저장이됨 그러고 나서 로그인후 req.user로 접근가능.
loginError: req.flash('loginError'), //일회성 메세지들 보여주기위해 에러 넣음
});
});

 

 

즉 이뜻이 then(user => done(null, user))

req.user에 넣어준다는 이야기인가요?

 

 

 

 

 

답변 1

답변을 작성해보세요.

1

일단 passport.session이 deserializeUser을 실행하지만. deserializeUser는 serializeUser 후에 모든 라우터 접근 시 실행됩니다.

passport는 남이 만든 라이브러리라서 매개변수나 옵션같은 것은 남이 정해둔 대로 하는 겁니다. req.body.email같은 것도 email만 쓰도록 정해져있는거고 email password done도 다 그 자리에 고정되어 있는 것입니다. 그냥 외우셔야 합니다. 원리같은 게 없습니다. 내부 코드를 보고싶다면 passportjs 깃허브에 있습니다.

strategy의 done함수는 passport.authenticate의 콜백함수로 인수들을 넘깁니다. serializeUser의 done 함수는 에러가 없을 시 세션에 인수를 저장합니다. deserializeUser의 done함수는 req.user을 만듭니다.(에러가 없을 시)

함수 앞에 async도 인자가 아니라 키워드로 await을 쓰고싶을때 아무때나 붙이면 됩니다.