http://www.passportjs.org/docs/authenticate/
router.post('/login', function(req, res) {
passport.authenticate('local', function(err, user, info) {
console.log("let's see")
if (err) { return res.status(404).json({ message : 'failed'}) }
if (!user) {
// *** Display message without using flash option
// re-render the login form with a message
console.log("unauthorized !!!")
console.log("error message :", info.message)
return res.status(404).json({ message: info.message })
}
req.logIn(user, function(err) {
if (err) { return res.status(404).json({ message : 'failed'}) }
console.log("Authorization succeed")
return res.status(200).json({message : info.message})
});
})(req, res);
});
// LocalStrategy : for Client
passport.use('local', new LocalStrategy({
usernameField: 'id',
passwordField: 'password',
// allow req variable in afterward callback function
failWithError: true
},
// 사용자가 정보를 전달할 때마다 아래의 콜백함수가 실행된다
async function(username, password, done,) {
// 여기서 username은 사실상 우리가 입력하는 ID이다
console.log('LocalStrategy ', username, password)
// 해당 id 의 user 가 존재하는지 확인한다
function FindUser(){
return new Promise((resolve, reject) => {
// write query
const query = `SELECT * FROM member WHERE Id = '${username}'`;
connection.db_rest.query(query, (err, results) => {
// err 발생시 아래의 코드를 통해 catch block이 error를 잡아낼 것이다
if(err) {
console.log("User Finding Error")
reject(new Error(err.message))
}
// resolve는 최종 데이터를 전달한다 ( results를 response 에게...? )
resolve(results)
})
});
}
FindUser()
.then(result => {
console.log(result)
try {
// 사용자가 존재하지 않는 다는 것
if(response[0] == undefined){
console.log("no user matched")
// 그렇지 않으면 login이 되지 않은 것이다
// message : 'Incorrect password' 를 하게 되면
// session-store 상에, 'flash' : { 'error' : ["Incorrect user"} 이라는 기록이 남는다
// done(null,false) : there is no error but there is no user either
return done(null, false, {message :'Incorrect ID'})
}else{
// 해당 사용자가 존재한다면 : ccmpare password
if( bcrypt.compare(password,response[0].Password )){
let authData = response[0]
// 참고: 2번째 인자로 false 가 아닌 값을 넣어준다 ( js 에서는 false 가 아닌 값을 true 로 친다 )
// authData 를 2번째 인자로 사용한다는 것은 : 로그인에 성공했으니, 성공한 사용자의 정보는 ~다 ! 라고 알려주는 것
// 그리고, 아래와 같이, done 함수의 2번째 인자로 false 가 아닌, 다른 값이 들어오면, passport.serialize 함수를 자동으로 호출한다
// 그런데 !!!
// 아래 코드를 실행하려면 : passport.initialize() middleware를 사용해야 한다
// app.use(passport.initialize())를 사용해야 한다
return done(null, authData, { message :'success'})
}else{
return done(null, false, { message : 'Password is incorrect'})
}
}
} catch (error) {
console.log("error :", error)
done(error, false,{ message : 'failed'} )
return ;
}
})
.catch(console.log)
}
))
Problem
Problem here is that
passport.js local strategy is executed
after !!!
which means
as you can see in this console,
passport.js local strategy is executed after !!!
< front >
<form action="/auth/login" id = "loginForm" method="post" style="text-align:center">
<legend><h2>일반회원 로그인</h2></legend>
<hr />
<input type="text" class="verify_id" name="id" id="myid" autofocus required placeholder="아이디" style="margin:10px auto; height:30px;font-size:16px;" ><br />
<input type="password" class="verify_pw" name="password" required placeholder="비밀번호" style="margin:10px auto; height:30px;font-size:16px;" ><br />
<div class="login-button" style=" width:200px; height:40px;font-size:16px; ">
<input id = "loginBtn" type="submit" value = "로그인" style = " letter-spacing: 1.2;font-weight: 600; margin-top: 1vh;width:100%; height: 100%;background-color:#19bf19;color:white; border:none; border-radius:5px;" >
</div>
<a href="/google">
<div style="box-shadow: 0px 5px 10px 0px rgba(0,0,0,.25);
-o-box-shadow: 0px 5px 10px 0px rgba(0,0,0,.25);
-ms-box-shadow: 0px 5px 10px 0px rgba(0,0,0,.25);
-moz-box-shadow: 0px 5px 10px 0px rgba(0,0,0,.25); border-radius: 5px; width:200px; height:40px;font-size:16px;margin-top:1.5vh;background-color: lightskyblue; display: flex;align-items: center;justify-content: center;" >
<i style = "color: white; margin-right:1vh;"class="fab fa-google-plus-g"></i><span style = "color: white; font-weight: 600;">Google Login</span>
</div>
</a>
<h5><a href="/auth/register" class="login_text">회원가입 |</a> <a href="/auth/findAccount" class="login_text" >아이디, 비밀번호 찾기</a><br /><br />
</form>
As you see, in the "로그인" btn :
it is "button" type, not "submit" type
< Vanilla JS >
const loginForm = document.getElementById('loginForm')
loginBtn.addEventListener('submit', (event) => {
const loginId = document.querySelector('#myid').value
const loginPwd = document.querySelector('.verify_pw').value
So
1) With input type = "submit"
2) VS : FORM.addEventListenter ("submit")
it is sending twice
1) input type = "button"
2) VS
3) Passport.js
usernameField: 'username',
passwordField: 'password',
4) match the name of the input
<input type="text" class="verify_id" name="id" id="myid" autofocus required placeholder="아이디" style="margin:10px auto; height:30px;font-size:16px;" ><br />
<input type="password" class="verify_pw" name="password" required placeholder="비밀번호" style="margin:10px auto; height:30px;font-size:16px;" ><br />