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);
});