[방울이] 인증/인가 & 카카오 소셜 로그인 구현

sunnny·2023년 7월 31일
1

Spring

목록 보기
2/2
post-thumbnail

인증 & 인가 개념 정리

  • 인증 (Authentication) = 로그인
    • 자격 증명 확인 (Auth)
    • 사용자의 신원을 확인하는 과정

  • 인가 (Authorization)
    • 권한 허가 or 거부
    • 어떤 개체가 어떤 리소스에 접근할 수 있는지 or 어떤 동작을 수행할 수 있는지를 검증하는 것

인증, 인가 구현 방식

1️⃣ 쿠키

  • 왜 쿠키를 사용해야 할까?
    HTTP는 비연결성 프로토콜이다. (무상태성, stateless)
    -> 요청 간의 상태를 유지하는 것이 필요한 경우가 존재한다.
  • 쿠키 : 사용자가 어떤 웹사이트를 방문할 때, 그 사이트가 사용하고 있는 서버를 통해 사용자의 브라우저 안에 생성되는 정보 기록 데이터
  • 이 방식의 단점
    • 클라이언트가 서버로 요청을 보낼 때 쿠키 값을 그대로 보내기 때문에
      조작 및 유출의 위험이 있다.
    • 용량 제한이 있어 많은 데이터 정보를 담을 수 없다.
  • 이를 해결하기 위해선!
    • 사용자의 중요한 정보는 모두 서버에 저장되어야 한다.
    • 클라이언트와 서버는 (탈취를 막기 위해) 추정 불가능한 임의의 식별자 값으로 연결해야 한다.

2️⃣ 세션

  • 사용자에 대한 정보를 모두 서버에 저장한다!
  • 클라이언트가 가지고 있는 것이 SessionId 밖에 없다. (조작 및 유출 위험⬇️)
  • 이 방식에서 Cookie는 SessionId를 전달하기 위한 매개체로 사용된다.
    (그래서 session cookie 방식이라고도 함)

  • 서버는 SessionId를 사용하여 클라이언트의 정보와 상태를 유지한다. (stateful)
    세션은 일정 시간동안 유지된다.

세션을 통한 인증, 인가가 이루어지는 과정

1. 사용자 로그인
2~5. 서버는 관련 정보를 세션 저장소에 저장하고, 사용자에게 SessionId를 발급한다. (by. 쿠키)
6. 브라우저는 인증 후 모든 요청마다 HTTP Header cookie 부분에 SessionId를 포함하여 서버에 전송한다.
7~9. 서버는 전달받은 SessionId에 해당하는 세션 정보가 세션 저장소에 존재하면 사용자가 인증되었다고 판단한다.
10. 사용자가 로그아웃 하면 해당 세션 데이터가 서버 측에서 삭제된다.

  • 인가가 필요한 요청이 있을 때마다 쿠키에 담긴 SessionId를 통해 세션 DB를 조회하여 권한을 확인한다.

  • 세션 방식의 장점

    • 사용자의 정보들을 이용한 새로운 기능 추가 가능
    • 보안 측면에서 더 유리하다.
  • 세션 방식의 단점

    • 트래픽이 많아져서 서버 확장이 필수적일 때 세션 정보를 어떻게 관리할 지에 대한 큰 번거로움이 존재한다.
    • Server와 DB의 부담 증가 → Redis를 사용 (빠르고 저렴)
    • SessionId 자체를 탈취하여 사용자인 척 위장이 가능하다.

3️⃣ 토큰

토큰을 통한 인증, 인가가 이루어지는 과정

1. 사용자 로그인
2~3. 서버에서는 JWT(access token)를 발급한다.
4. 생성된 토큰을 클라이언트에게 보낸다.
클라이언트는 토큰을 받아서 local Storage에 저장하고, 사용자가 로그아웃하면 저장된 토큰을 삭제한다.
5. 인증 및 인가가 필요한 요청을 할 때마다 클라이언트는 HTTP Header의 Authorization 부분에 토큰을 담아서 보낸다.
6~7. 서버 측은 요청+토큰을 받으면 JWT의 header와 payload 값을 서버 측에 감춰둔 secret key를 통해 복호화하고, 복호화한 값을 계산한다.
계산 결과값과 signature값이 일치하고, 유효기간도 만료되지 않았다면 해당 사용자는 이후 모든 요청에 대해 로그인된 회원으로 권한을 인가한다.

JWT (JSON Web Token)

JSON을 이용해서 정보를 안전하게 다루기 위한 개방형 표준 (RFC 7519) 방법
JWT에는 민감한 정보를 절대로 담지 말아야 한다!

  • 토큰의 구조

    • Header : 토큰의 타입(JWT)과 알고리즘 정보가 들어있다.
    • Payload : 사용자의 정보나 데이터 속성 등의 claim이 들어있다.
      (누가 누구에게 발급했는지, 토큰의 유효기간, 사용자 이름, role 등의 정보가 담겨있다.)
      -> JWT는 탈취의 위험성이 있기 때문에, 그대로 사용하는것이 아닌 Access Token, Refresh Token 으로 이중으로 나누어 인증을 하는 방식을 취한다.

JWT 🆚 access token 🆚 refresh token

  • JWT : 정보를 안전하게 전송하기 위해 표준화 된 방법 중 하나.
    토큰 자체에 정보를 저장할 수 있다.
    access token이나 refresh token을 JWT로 구현할 수도 있고, 아닐 수도 있다.
  • access token : 수명이 짧다. (30분)
  • refresh token : 수명이 길다. (2주)

사용자가 회원가입 or 로그인 했을 때 서버는 access token, refresh token 두개를 발급한다. 클라이언트는 두 token 모두 저장해 둔다.
평소에 API 통신할 때는 Access Token을 사용하고, Refresh Token은 Access Token이 만료되어 갱신될 때만 사용한다.

↳ 그럼 수명이 긴 refresh token이 탈취되면 어떡하지??
클라이언트가 Access Token를 재요청할 때마다 Refresh Token도 새로 발급받는 Refresh Token Rotation방식을 사용하자!

  • 토큰 방식의 장점
    • 세션 기반의 인증 방식과 달리 인증 정보가 토큰에 저장되므로 DB 확장에 유리하다.
    • 생성된 Token을 추적하지 않고, 유효 여부만 따지기 때문에 빠른 처리가 가능
    • DB필요X
    • 구현이 매우 쉽다.
  • 토큰 방식의 단점
    • Session 만큼의 추가 기능을 구현할 수 없다.
    • payload 자체는 암호화되지 않아서 사용자의 중요한 정보를 담을 수 없다.
    • 토큰 탈취 시 대처하기 어렵다. -> 해결책 : 만료 시간을 짧게 한다.
    • 토큰 자체의 길이가 길어서 인증 요청이 많아질수록 네트워크 부하가 심해진다.

OAuth란?

: Open Authorization

  • 사용자가 우리의 서비스(클라이언트)에게 자신의 플랫폼(카카오톡) 정보에 접근할 수 있는 권한을 위임함 것
  • 네이버, 카카오, 애플과 같은 다양한 플랫폼의 특정한 사용자 데이터에 접근하기 위해 제3자 클라이언트(우리의 서비스)가 사용자의 접근 권한을 위임(Delegated Authorization)받을 수 있는 표준 프로토콜
    인증 처리 (카카오 인증 서버로부터 code를 받음)
    인가 처리 (=권한 부여, 카카오 인증 서버로부터 access token을 받음)

카카오 소셜로그인 과정 이해하기

Step 1 : 카카오 로그인

인증 처리 : 코드를 부여받음

1️⃣ 사용자가 카카오 로그인 버튼 클릭 (카카오 로그인 요청)

2️⃣ 클라이언트가 카카오 인증 서버로 인가 코드 발급을 요청

3️⃣ 카카오 인증 서버가 사용자에게 인증/로그인 요청한다.
(로그인 안된 상태라면 카카오 로그인 창이 뜸. 이미 되어있다면 이 과정 생략)

4️⃣ 사용자 인증/로그인 성공 시, 카카오 인증 서버가 사용자에게 동의 화면을 출력한다.

5️⃣ 카카오 인증 서버가 인가 코드(Authorization Code)를 발급해 Redirect URI로 전달한다.

인가 처리 : 권한(access token)을 부여받음

6️⃣ 클라이언트가 카카오 인증 서버로 인가코드를 이용하여 토큰을 요청한다.
(카카오 리소스 서버의 데이터에 접근할 수 있는 권한을 요청)

7️⃣ 카카오 인증 서버가 코드값이 정상인지 확인, 정상이면 access token을 부여한다.

👊🏻 서버는 발급받은 토큰으로 사용자 정보만 가져오는 기능만 구현하면 된다.
👊🏻 정리!!
소셜로그인 버튼 클릭 -> 카카오 로그인 -> (여기는 프론트가 알아서 해줌)
-> 로그인 성공하면 서버는 카카오 서버로부터 인가코드를 받음


Step 2 : 회원정보 가져오기 & 우리 서비스 회원가입

8️⃣ 클라이언트는 발급받은 토큰으로 리소스 서버에 사용자 정보 가져오기를 요청

  • get/post 메서드
  • 로그인 성공 후 발급받은 엑세스 토큰을 통해 인증한 후, 사용자 정보를 가져온다.

9️⃣ 카카오 인증 서버가 토큰의 유효성을 검증, 요청을 처리

🔟 클라이언트는 카카오에서 제공받은 정보를 통해 사용자가 기존에 등록되어 있는 회원인지 확인한다.

  • 이미 회원 가입된 사용자 : step3로 ㄱㄱ
  • 등록되지 않은 사용자 : 카카오에서 제공받은 정보로 서비스 데이터베이스에 회원가입 처리

Step 3 : 서비스 로그인

1️⃣ 우리 서비스의 서버(OAuth 용어에서는 클라이언트를 의미함)가 사용자의 id에 대한 세션을 발급

2️⃣ 우리 서비스의 클라이언트는 서비스 세션을 전달받아 로그인 완료 처리를 하고, 사용자를 로그인된 홈화면으로 이동시킨다.


yml파일 설정

oauth:
  kakao:
    client-id: ${KAKAO_CLIENT_ID}
    client-secret: ${KAKAO_CLIENT_SECRET}
    redirect-uri: ${KAKAO_REDIRECT_URI}

KAKAO_CLIENT_ID : 애플리케이션 등록 후 생성되는 App Key 정보 중 REST API 키 값KAKAO_CLIENT_SECRET : Kakao Developers > 내 애플리케이션 > 제품 설정 > 보안 메뉴에서 생성
KAKAO_REDIRECT_URI : Kakao Developers > 내 애플리케이션 > 제풀 설정 > 카카오 로그인 > Redirect URI

출처

1개의 댓글

comment-user-thumbnail
2023년 7월 31일

정보 감사합니다.

답글 달기