여유상점_0907 : 5) Passport Local Strategy 400 Error ( Bad Request )

오범준·2020년 9월 9일
0

Error 1)

Route

// 아래 'local' 이라는 것은 수많은 passport 방식 중에서
// username, password를 이용해서 로그인 하는 기능을 의미한다 
router.post('/login', passport.authenticate('local'), (req, res) => {
        if(err) console.log(err) 
        // If this function gets called, authentication was successful.
        // `req.user` contains the authenticated user.
        res.redirect('/users/' + req.user.username);
})

Passport

passport.use('local', new LocalStrategy(
        {
            // email과 pwd는 html 상에서 form tag 안에 들어있는 input 들의 name이다
            // passport는 form 형식으로 입력값을 받는데, 받을 때, 무조건 따라야 하는 형식 및 이름이 있다
            // 아래의 코드들을 통해서, 그러한 형식들을 맞춰주는 것이다 
            usernameField : 'id',
            passwordField : 'pw'
        },
        // 사용자가 정보를 전달할 때마다 아래의 콜백함수가 실행된다
        async function(username, password, done) {

            console.log('LocalStrategy ', username, password)

            const response = await new Promise((resolve, reject) => {
                // write query
                const query = `SELECT * FROM user_person WHERE email = '${email}'`;
    
                connection.db.query(query, (err, results) => {
                    // err 발생시 아래의 코드를 통해 catch block이 error를 잡아낼 것이다 
                    if(err) reject(new Error(err.message)) 
                    // resolve는 최종 데이터를 전달한다 ( results를 response 에게...? )
                    resolve(results)
                })
            });

            console.log("Response result in local login :", response);
            return;
            }

1st Trial : add 'failureRedirect'

router.post('/login', passport.authenticate('local', { failureRedirect : '/'), (req, res) => {

It worked, It was going back to '/'

So Now I have to handle how to
deal with fail cases

It seems like. passport middleware is not receving the info properly from
the info sent from the client

    // LocalStrategy
    passport.use('local', new LocalStrategy(
    {
        // email과 pwd는 html 상에서 form tag 안에 들어있는 input 들의 name이다
        // passport는 form 형식으로 입력값을 받는데, 받을 때, 무조건 따라야 하는 형식 및 이름이 있다
        // 아래의 코드들을 통해서, 그러한 형식들을 맞춰주는 것이다 
        usernameField : 'email',
        passwordField : 'password'
    },

Solution :

1) add '{usernameField: 'id',passwordField: 'password'}'

2) app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies

Error 2)

When I click "로그인", following error occurs

Error: Failed to serialize user into session

< code >

passport.serializeUser(function(user, done) {
    // 아래에서 넘겨온 유저의 정보가 user 라는 변수에 들어있고
    // 넘겨받을 때, user 라는 변수안에는 email과 password라는 것이 저장되어 있다
    // done이라는 함수의 2번째 인자로, 사용자의 식별자를 넣어준다 
    // 이 경우, session 폴더 안의 , 세션 데이터( 파일) 안에 passport.user 값으로, user.email 을 넣어주는 것이다 
    // 그리고 passport.user 값으로 들어간, user.email이라는 값은,
    // deserializeUser 안의 콜백 함수의 첫번째 인자, id 로 들어가게 되고
    // 이는 특정 사용자를 식별하는 식별자 역할을 하게 된다 
    console.log("serializeUser", user);

    // 관리자일 경우, id를 저장
    if(user.admin){
        done(null, user.Id);
    }else{
        // 클라이언트일 경우, email 저장
        done(null, user.Id);
    }
    });
    // passport에 deserializeUser 라는 기능 설치 
    // 기본적 기능 : session-store에 저장된 데이터를 기준으로 해서, 우리가 필요한 정보를 조회할 때 사용한다 
    // 자. login이 되고나면, 사용자가 각 페이지를 이동할 때마다, 
    // 그 사용자가 login 된 사용자인지 아닌지를 판단할 필요가 있다
    // 이때 passport는 deserializeuser를 호출한다 
    // 그렇기 때문에, 페이지를 이동하거나 reload 할 때마다, 페이지를 열 때마다 deserializeuser 함수는 호출된다 
    // 즉, deserialzeUser는 session-store로 부터, 식별자를 가져오는 것이다
  passport.deserializeUser(function(Id, done) {
    console.log("deserializeUser", Id);
    const query = `SELECT DISTINCT * FROM member WHERE Email = '${Id}'`;
    connection.db_rest.query(query, (err, user) => {
            // err 발생시 아래의 코드를 통해 catch block이 error를 잡아낼 것이다 
            if(err){
                // there is err and there is no user
                done(err,false)
            } 
            else if(user){
                console.log("user", user)
                done(null,user)
            }
        })
  });

You have to check
whether you are unifying the form of
"deserialzie" + "serialize"

The reason Why above Error occured is because

I used "user.Email" when serializing
and used "user.Id" when deserializing

profile
Dream of being "물빵개" ( Go abroad for Dance and Programming)

0개의 댓글