[NodeJS] 소셜 로그인 구현(1) - 카카오톡

seonjeong·2023년 6월 25일

NodeJS

목록 보기
15/19
post-thumbnail

💖 카카오톡 소셜 로그인 설정

Kakao Developers - REST API를 이용한 로그인

1. 애플리케이션 추가

2. 플랫폼 등록

프론트 URL 입력할 것

3. 로그인 활성화, Redirect URI

활성화 상태 on

카카오 로그인에서 사용할 OAuth Redirect URI 설정

4. 동의 항목 설정


💖 카카오톡 소셜 로그인 구현

내가 구현한 방식은 다음과 같다.

1. 인가코드 받기

카카오 로그인 클릭 시 동의 페이지로 이동하고 동의하고 계속하기를 클릭하면 인가 코드를 받을 수 있다.

public socialConnection = async () => {
    const authorizationUrl = `https://kauth.kakao.com/oauth/authorize?client_id=${KAKAO_REST_API_KEY}&redirect_uri=${KAKAO_REDIRECT_URI}&response_type=code`;
    return authorizationUrl;

    throw new InternalServerError("소셜 로그인 연결 실패");
  };

2. 인가코드를 이용하여 토큰 발급

public getAccessToken = async (code: string) => {
    try {
      const data = {
        grant_type: "authorization_code",
        client_id: KAKAO_REST_API_KEY,
        redirect_uri: KAKAO_REDIRECT_URI,
        code: code,
      };

      // 2-1. 엑세스 토큰 발급
      const response = await axios.post(
        "https://kauth.kakao.com/oauth/token",
        data,
        {
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
        }
      );

      const ACCESS_TOKEN = response.data.access_token;
      const SCOPE: string = response.data.scope;

      // 2-2. 이메일 정보가 없을 시 회원가입 불가
      if (!SCOPE.includes("account_email")) {
        return;
      }

      return ACCESS_TOKEN;
    } catch (err) {
      throw new InternalServerError("kakao-login : 토큰 발급 실패");
    }
  };

3. 사용자 정보 취득

public getUserInfo = async (token: string, type: string) => {
  // 3-1. 토큰을 이용하여 소셜 회원 정보 취득 후
  try {
    const res = await axios.get("https://kapi.kakao.com/v2/user/me", {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });

    const account = res.data.kakao_account;
    const userData = {
      social_id: res.data.id,
      nickname: account.profile.nickname,
      email: account.email,
    };

    // 3-2. 가입여부 확인
    const existingUser = await User.findOne({
      where: { email: userData.email },
    });

    // 3-3. 가입되지 않은 사용자일 경우, 회원가입
    if (existingUser === null) await this.addUser(userData);

    // 3-4. 회원 조회하여 id, nickname 취득
    const user = await User.findOne({
      where: {
        email: userData.email,
        social_id: userData.social_id,
      },
    });

    const userInfo = {
      id: user?.id,
      nickname: user?.nickname,
      type: type,
    };

    return userInfo;
  } catch (err) {
    throw new InternalServerError("kakao-login : 사용자 정보 취득 실패");
  }
};

4. 서비스 전용 토큰 발급

서비스 전용 토큰은 JWT를 이용하여 발급했다

public generateToken = async (userInfo: any) => {
  try {
    const tokenUtil = new TokenUtil(userInfo.id, userInfo.nickname);

    const newToken = (expiresIn: string) => {
      const token = tokenUtil.generateToken(SECRET_KEY!, expiresIn);
      return token;
    };

    const serviceToken = newToken("2h");

    return serviceToken;
  } catch (err) {
    console.log(err);
    throw new InternalServerError("kakao-login : 서비스 전용 토큰 발급 실패");
  }
};
profile
🦋개발 공부 기록🦋

0개의 댓글