[Node.js][TIL] passport 카카오, 네이버 사용하기

Trippy·2023년 11월 24일
0

Node.js

목록 보기
15/28

회원가입 CRUD와 로그인 구현을 끝내고 passport를 했다. passport는 Node.js용 미들 인증웨어이다. 그동안 회원 가입을 구현하면서 백으로 api만 만들다가 실제로 사용되고 있는 sns 로그인을 구현하고자 하니까 신기했다.

카카오 로그인 Oauth 신청

Kakao Developers 홈페이지

신청 과정은 검색하면 워낙 잘 설명 되어 있는 정보가 넘쳐나기 때문에 생략.
하지만 아래의 두 가지는 확실히 해야 한다.

사이트 도메인 : http://localhost:3000
Redirect URI : http://localhost:3000/api/auth/kakao/callback

나는 여기서 RESP API키를 사용 할 것이다.
환경 변수로 지정 해준다.


카카오 로그인 라우터 strategy 구현

카카오 로그인은 로그인 인증 과정을 카카오에게 맡긴다.

사용자는 번거롭게 새로운 사이트에 회원가입을 매번 할 필요가 없어지고, 서비스 제공자는 로그인 과정을 검증된 SNS에 맡길 수 있어 편리하다.

SNS 로그인의 특징은 회원가입의 절차가 따로 없다.

카카오로 예시를 들 경우, 로그인만 하면, 따로 회원가입 절차 없이 사이트에 로그인 할 수 있는걸 봤을 것이다.

passport-kakao 설치

yarn add express-session passport passport-kakao

/app.js

import express from "express";
import session from "express-session";
import passport from "passport"
.
.
.
// 세션
app.use(
    session({
        secret: process.env.SECRET_KEY,
        resave: false,
        saveUninitialized: false,
        cookie: { secure: false },
    }),
);
app.use(passport.initialize());
app.use(passport.session());

//시리얼라이즈
passport.serializeUser((user, done) => {
    done(null, user.id);
});

//디시리얼라이즈
passport.deserializeUser(async (id, done) => {
    try {
        const user = await Users.findByPk(id);
        done(null, user);
    } catch (error) {
        console.log(error);
        done(error);
    }
});
.
.
.
app.get('/', (req, res) => {
  res.send("서버가 켜졌습니다");
});

./routers/auth.js

import {Router} from "express";
import passport from "passport";
const authRouter = Router();
.
.
.
// 카카오 로그인 API
authRouter.get("/kakao", passport.authenticate("kakao"));
authRouter.get(
    "/kakao/callback",
    passport.authenticate("kakao", {
        failureRedirect: "/?error=카카오로그인 실패",
    }),
    (req, res) => {
        res.status(200).redirect("/"); // 성공 시에는 /로 이동
    },
);

./passport/kakaoStrategy.js

import passport from "passport";
import { Strategy as KakaoStrategy } from "passport-kakao";
import db from "../models/index.js";
const { Users } = db;


const kakaostrategy = () => {
    passport.use(
        "kakao",
        new KakaoStrategy(
            {
                clientID: process.env.KAKAO_ID,
                callbackURL: "http://localhost:3000/api/auth/kakao/callback",
            },
            async (accessToken, refreshToken, profile, done) => {
                console.log("kakao profile", profile);
                try {
                    const exUser = await Users.findOne({
                      // users db의 email중 `해당 이메일과 일치 하는 경우`
                        where: { email: `kakao${profile._json.id}@kakao.com` },
                    });
                  // 이미 가입된 카카오 프로필이면 성공
                    if (exUser) {
                        console.log("가입 이력 있음", accessToken);
                        done(null, exUser);
                    } else {
                      // 가입되지 않는 유저면 회원가입 시키고 로그인을 시킨다.
                        const newUser = await Users.create({
                            email: `kakao${profile.id}@kakao.com`,
                            nickName: profile.displayName,
                            imgUrl: profile._json.properties.profile_image,
                            password: profile.id,
                            refreshToken: refreshToken,
                            type: "kakao",
                        });
                        console.log("가입 이력 없음", accessToken);
                        done(null, newUser);
                    }
                } catch (error) {
                    console.error(error);
                    done(error);
                }
            },
        ),
    );
};

export { kakaostrategy };

./routers/index.js

import { Router } from "express";
import { userRouter } from "./users.router.js";
import { authRouter } from "./auth.router.js";
import passport from "passport";
// 카카오 strategy import
import { kakaostrategy } from "../passport/kakaoStrategy.js";

const apiRouter = Router();

apiRouter.use("/user", userRouter);
// kakaostrategy 미들웨어 실행
kakaostrategy();
apiRouter.use("/auth", authRouter);

export { apiRouter };

결과

데이터가 잘 들어왔다.

profile
감금 당하고 개발만 하고 싶어요

0개의 댓글