여유상점_09228 : 15) Double Form Submission, Passport.js Custom error handling , sending back message to client
http://www.passportjs.org/docs/authenticate/
Trial 1. Custom Callback Function
"router"
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);
});
"Passport"
// 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 !!!
Problem of sending form twice
< 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
Solution
1) input type = "button"
2) VS
- BUTTON.addEventListenter("click")
- body : JSON.stringfy({
username : ~
password : ~
})
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 />
Author And Source
이 문제에 관하여(여유상점_09228 : 15) Double Form Submission, Passport.js Custom error handling , sending back message to client), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dhsys112/여유상점09228-15-Passport.js-error-handling-sending-back-message-to-client저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)