Passport.js를 이용한 로그인 (with 외부 Login API)

디그다·2022년 11월 10일

Passport.js를 사용하려고 자료를 찾아보면
WebServer와 DB를 직접 연결하여 쿼리문을 통해 사용자 정보를 찾는 예제들만 가득했다.

나의 개발 환경은 Frontend / Backend가 분리되어있기 때문에
외부에 있는 API를 호출하여 로그인 여부를 확인해야 했고,
이 방법이 정석인지는 모르겠지만.. 내 필요사항에 맞추어 아래와 같이 수정하여 사용했다.

그 외 다른 설정들은 인터넷 예제와 동일하므로 생략한다.

/**
 * 로그인 여부를 확인해주는 localStrategy
 */
passport.use("local", new LocalStorage({usernameField: "userId"}, async (username, password, done) => {
    const params = {
        userId: username,
        password: password
    };

  	// 외부 API 호출할게
    const res = await fetch(process.env.NEXT_PUBLIC_API_HOST + "/login", {
        method: "POST",
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify(params)
    });
  
	// 외부 API 응답이 Success이든지 Error이든지 관심없고 일단 받은 Response를 Ajax 응답으로 그대로 보낼게
  	// (타 예제에서는 쿼리를 통해 사용자 정보가 있는 경우 두 번째 인자에 user 정보를 넣어주고, 사용자 정보가 없으면 null을 넣어줌)
    return done(null, res);
}));



/**
 * 브라우저에서 Ajax를 통해 /login API 호출 시 아래 코드 실행
 */
  router.post("/login", (req, res, next) => {

    passport.authenticate("local", 						// localStrategy를 이용해서 로그인 여부를 판단할게.
                          {failureRedirect: "/login"},  // 로그인 실패하면 "/login" URL로 리디렉션 시킬게
                          async (err, loginRes) => {    // localStrategy 실행 중 에러면 err, 성공이면 loginRes 변수에 값을 담아올게

      	// 에러니까 브라우저의 Ajax 응답으로 400을 줄게
        if (err) {
            return res.status(400).json({err});
        }
      
      	// 외부 API로부터 Success 응답을 받은 경우
        if (loginRes.ok) {
          
            // 외부 Login API를 호출하여 받은 Response를 json형태로 파싱
            const loginResData = await loginRes.json();
          
            // 로그인 성공
            // passport에 저장할 user 정보
            const user = {
                isLogin: true,			// 로그인 성공했다고 Session에 저장할게 (선택사항)
                ...loginResData.data	// 외부 Login API로부터 받은 응답 중에 Session에 저장하고싶은 값 뽑아서 저장할게 (선택사항)
            };

            // passport에 저장
            req.logIn(user, (error) => {
                if (error) {
                    return next(error);
                }

                // 브라우저 ajax 응답으로 Login API에서 받은 값 그대로 줄게
                return res.status(loginResData.status).json(loginResData);
            });
        } else {
            // 로그인 실패
          
            // 외부 Login API를 호출하여 받은 Response를 json형태로 파싱
            const loginResData = await loginRes.json();
          
            // 브라우저 ajax 응답으로 Login API에서 받은 값 그대로 줄게
            return res.status(loginResData.status).json(loginResData);
        }
    })(req, res, next);
});

profile
매일매일 삽질중인, 열심히 땅을 파고있는 개발자

0개의 댓글