OAuth 2.0으로 소셜 로그인 구현하기 - (Kakao)

FE_04이상민·2024년 9월 4일
0

Node.js

목록 보기
1/1
post-thumbnail

OAuth2.0의 개념

OAuth2.0이란 무엇인가요?

OAuth 2.0(Open Authorization 2.0)은 인터넷 사용자들이 비밀번호를 공유하지 않고도 자신이 사용하는 서비스 간에 안전하게 자격 증명을 위임할 수 있게 해주는 업계 표준 프로토콜입니다.

OAuth2.0의 구성 요소

  1. Resource Owner (리소스 소유자):
    자원에 대한 소유자이며, 일반적으로 최종 사용자(End User)입니다.
  2. Client (클라이언트):
    리소스 소유자를 대신하여 자원 서버에 접근을 요청하는 애플리케이션입니다.
  3. Authorization Server (인가 서버):
    클라이언트의 접근 요청을 인증하고 승인하는 서버입니다.
  4. Resource Server (자원 서버):
    보호된 자원(데이터)을 호스팅하는 서버입니다.
  5. Access Token (액세스 토큰):
    인가 서버가 클라이언트에게 발급하는 자격 증명으로, 클라이언트가 자원 서버에 접근할 수 있는 권한을 증명합니다.

OAuth2.0의 흐름 과정

  1. 클라이언트가 인가 코드를 요청:
    사용자가 클라이언트(애플리케이션)를 통해 자원에 접근하려고 하면, 클라이언트는 인가 서버로 사용자를 리디렉션합니다.
    클라이언트는 클라이언트 ID, 리디렉션 URI, 응답 유형(response type) 등을 포함한 요청을 인가 서버에 보냅니다.

  2. 사용자 인증 및 승인:
    인가 서버는 사용자에게 로그인 및 권한 부여를 요청합니다.
    사용자가 성공적으로 로그인하고 클라이언트에 대한 접근을 승인하면, 인가 서버는 클라이언트에 사전 등록된 리디렉션 URI로 인가 코드를 전달합니다.

  3. 클라이언트가 액세스 토큰 요청:
    클라이언트는 받은 인가 코드를 사용하여 인가 서버에 액세스 토큰을 요청합니다.
    이 요청에는 인가 코드, 클라이언트 ID, 클라이언트 시크릿, 리디렉션 URI 등이 포함됩니다.

  4. 인가 서버가 액세스 토큰 발급:
    인가 서버는 클라이언트를 인증하고 요청이 유효한지 확인한 후, 액세스 토큰과 (선택적으로) 리프레시 토큰을 발급합니다.

  5. 클라이언트가 자원 서버에 요청:
    클라이언트는 액세스 토큰을 사용하여 자원 서버에 보호된 자원에 대한 접근을 요청합니다.
    자원 서버는 액세스 토큰의 유효성을 검증한 후 요청된 자원을 반환합니다.

인가코드(Authorization Code)란 무엇인가요?

인가 코드(Authorization Code) 는 OAuth 2.0 프로토콜에서 클라이언트 애플리케이션이 인가 서버로부터 액세스 토큰을 얻기 위해 사용하는 임시 코드입니다.
인가 코드는 클라이언트가 리소스 소유자의 권한을 받아 인가 서버에서 발급하는 것이며, 짧은 시간 동안만 유효합니다.

OAuth 2.0을 사용한 카카오 로그인 인증하기

• 애플리케이션 등록 ~ 로그인 과정까지의 블로깅 → 실제 코드 예제와 설명을 함께 작성해 주세요.

login.js

// Kakao SDK 초기화
Kakao.init('W8UWxgWBRXANaWQ86xKC9IKGYol8l7Jf'); // 실제 JavaScript 키 사용
console.log(Kakao.isInitialized()); // 초기화 확인 (true 출력)

Kakao.init(): Kakao SDK를 초기화합니다.
애플리케이션 등록 시 발급받은 JavaScript 키를 사용하여 SDK를 설정합니다.
Kakao.isInitialized(): SDK 초기화 여부를 확인합니다.
true가 출력되면 초기화가 성공적으로 완료된 것입니다.

// 버튼 요소 선택
const kakaoLoginButton = document.querySelector('#kakaologinbtn');
const userImage = document.querySelector('#user_image');
const userName = document.querySelector('#user_name');
const logoutButton = document.querySelector('#logout-btn');

const redirectURI = 'http://127.0.0.1:5500'; 

// 로그인 버튼 클릭 이벤트 핸들러
kakaoLoginButton.onclick = () => {
    Kakao.Auth.authorize({
        redirectUri: redirectURI 
    });
};

kakaoLoginButton.onclick: 로그인 버튼 클릭 시 Kakao 로그인 페이지로 리디렉션합니다.
로그인 후 redirectURI로 돌아오게 됩니다.

// 페이지 로드 후 Authorization Code 확인
window.onload = () => {
    const url = new URL(window.location.href);
    const urlParams = url.searchParams;
    const authorizationCode = urlParams.get('code');

    if (authorizationCode) {
        console.log('Authorization Code:', authorizationCode);

        // 서버로 Authorization Code를 전달하여 Access Token 요청
        axios.post('http://localhost:3000/kakao/login', {
            authorizationCode: authorizationCode
        })
        .then(response => {
            console.log('User Info:', response.data);
            userName.textContent = response.data.nickname;
            userImage.src = response.data.profile_image;
        })
        .catch(error => {
            console.error('Error fetching user info:', error);
        });
    }
};

window.onload: 페이지가 로드되면 현재 URL에서 Authorization Code를 추출합니다.
axios.post(): 서버로 Authorization Code를 전송하여 Access Token을 요청합니다.
응답 처리: 서버에서 받은 사용자 정보를 페이지에 표시합니다.

server.js

const express = require('express');
const cors = require('cors');
const axios = require('axios');

const app = express();

app.use(cors({
    origin: ['http://localhost:5500', 'http://127.0.0.1:5500'],
    methods: ["OPTIONS", "POST", "DELETE"],
}));

app.use(express.json());

const kakaoClientId = 'W8UWxgWBRXANaWQ86xKC9IKGYol8l7Jf'; // 실제 JavaScript 키 사용
const redirectURI = 'http://127.0.0.1:5500'; 
const clientSecret = ''; 

Express 설정: Express 서버를 설정하고 CORS를 사용하여 특정 도메인에서의 요청을 허용합니다.
kakaoClientId, redirectURI: Kakao 로그인 설정에 필요한 클라이언트 ID와 리디렉션 URI를 설정합니다.
clientSecret: 필요 시 클라이언트 비밀키를 설정합니다.

app.post('/kakao/login', async (req, res) => {
    const authorizationCode = req.body.authorizationCode;

    try {
        // Access Token 요청
        const tokenResponse = await axios.post('https://kauth.kakao.com/oauth/token', null, {
            params: {
                grant_type: 'authorization_code',
                client_id: kakaoClientId,
                redirect_uri: redirectURI,
                code: authorizationCode,
                client_secret: clientSecret, 
            },
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        });

        const accessToken = tokenResponse.data.access_token;

        // 사용자 정보 요청
        const userResponse = await axios.get('https://kapi.kakao.com/v2/user/me', {
            headers: {
                'Authorization': `Bearer ${accessToken}`
            }
        });

        const userInfo = userResponse.data;
        res.json({
            nickname: userInfo.properties.nickname,
            profile_image: userInfo.properties.profile_image
        });

    } catch (error) {
        console.error('Error during Kakao login process:', error);
        res.status(500).json({ message: 'Internal Server Error' });
    }
});

/kakao/login 엔드포인트: 클라이언트에서 받은 Authorization Code를 사용하여 Kakao의 Access Token을 요청합니다.
Access Token 요청: axios.post()를 사용하여 Kakao의 OAuth 서버에 Access Token을 요청합니다.
사용자 정보 요청: Access Token을 사용하여 Kakao API로부터 사용자 정보를 가져옵니다.
에러 처리: 에러가 발생하면 서버가 500 상태 코드와 함께 에러 메시지를 반환합니다.

app.listen(3000, () => console.log('서버 열림!'));

서버 시작: Express 서버를 포트 3000에서 실행합니다.

각 실행 결과에 알맞는 결과도 캡쳐하여 함께 업로드 해주세요.

0개의 댓글