[모영-프로젝트]OAuth로 로그인 구현하기(jwt, cookie,보안)

lee·2024년 2월 27일
0

모영 프로젝트

목록 보기
8/8

1. 로그인 방법


  • 요즘 사이트는 오어스로만 처리하는 곳도 많아진 추세가 있기도 했고, 간편한 디자인을 위해 OAuth로만 로그인과 회원가입을 진행했다.
  • 우리 팀은 백엔드에서 오어스 인증을 진행하였다.
  • 프론트엔드에서는 오어스 url요청과 토큰 저장, 리프레쉬 토큰 요청을 진행하였다.

- 📌 먼저 OAuth란 무엇인가?

OAuth란 Open Authorization의 약자이다.
: 애플리케이션이 특정 시스템의 보호된 리소스에 접근하기 위해, 사용자 인증(Authentication)을 통해 사용자의 리소스 접근 권한(Authorization)을 위임받는 것을 의미한다.

- OAuth의 주체

  • Resource Owner
    • OAuth인증을 통해 소셜 로그인을 하고 싶어하는 사용자를 뜻한다.
    • Resource는 사용자의 이름, 전화번호 등의 정보를 뜻한다.
  • Resource Server & Authorization Server
    • 사용자가 이미 사용중인 서비스(Naver,kakao,Google등)의 서버 중 사용자의 정보를 저장하고 있는 서버를 특정해서 Resource Server라고 부릅니다.
    • 이미 사용 중인 서비스의 서버 중 인증을 담당하는 서버를 특정해서 Authorization Server라고 부른다.
  • Application
    • 사용자가 소셜 로그인을 활용해 이용하고자 하는 서비스 환경을 뜻함.
    • 상황마다 다르다 경우에 따라 Client와 Server로 세분화해서 지칭하기도 함.

2. OAuth 인증 흐름

우리 프로젝트에서 사용한 OAuth 인증 흐름이다.
1. Client를 백엔드 서버로 생각을 하고
2. Authorization Server는 네이버,구글,카카오 등 로그인 요청한 사이트 인증 서버이고
3. Resource Server는 우리 백엔드 서버 DB이다.

- Client를 백엔드라고 한 이유 : 엄연히 백엔드와 프론트 두개다 이지만, 요청시 프론트엔드가 백엔드에서 보내준 오어스 url로 리다이렉트 요청을 하여 로그인 요청을(액세스 토큰 요청) 하고 로그인 성공시 액세스 토큰 전달을 백엔드에서 프론트엔드 주소로 리다이렉트 해서 보내주기 때문에 백엔드와 프론트엔드 두개다가 된다. 하지만 이해가 쉽게 요청하고 받는 곳은 백엔드에서 이뤄짐으로 백엔드로 칭했다.

- OAuth 로그인 코드

1번 액세스 토큰 요청 (프론트 단)

코드

구현화면

  • window.location.assing(url)을 사용해서 백엔드에서 보내준 오어스 url로 클릭시 이동하게 해준다.
  • 그러면 구현화면 사진처럼 해당 소셜로그인 화면으로 넘어간다.
    동의하여 가입또는 로그인하게되면 백엔드에서는 프론트에서 알려준 주소(path)로 토큰과 필요로한 회원정보를 엔드포인트에 담아 리다이렉트 해준다.

2번 액세스 토큰 전달

(소셜 로그인을 구글이라고 가정하고 설명하겠다.)
(인증서버 === Authorization Server)
1. 구글을 로그인하면 구글 인증서버에서 유효하다면 백엔드로 인증 토큰을 보내주고
2. 그 인증 토큰을 백엔드에서는 프론트로 보내주는다.
3. 보내주는 방법으로는 프론트에서 정한 path로 리다이렉트 해서 보내주는데, 토큰과 회원정보 등을 param에 담아서 보내준다.

코드

2-1 프론트에서 액세스 토큰 저장하기(회원정보 저장)

먼저 따로 callback컴포넌트로 받는 이유는 보안을 위해서이기도 하는데 param에 정보가 남아 있기에 중간에 callback에서 처리를 하고 홈페이지로 리다이렉트 처리해준다. 회원이 아니라면 회원정보 입력 페이지로 리다이렉트 한다.

코드

  1. param으로 정보를 보내주기 때문에 useSearchParams()를 사용하여 param정보를 가져올 수 있다.
  2. token을 저장하는 방법에는 LocalStorage와 SesstionStorage 등 방법이 있는데 보안 이슈가 있기때문에 Cookie에 저장하는 방식을 선택했다.

📌 여기서 잠깐!! 보안 이슈란?? 뭐가 있을까??

  • 1. XSS(Cross-Site Scripting) 공격 : 악성 스크립트를 이용하여 브라우저에서 악의적인 동작을 수행
    악성 JavaScript를 삽입해 실행하는 공격이다. 공격자가 웹 사이트를 방문할 때, 악성 스크립트가 담긴 링크를 클릭하게 하거나, 입력 폼에 악성 스크립트를 입력하게 함으로 발생한다.
    이 공격으로 사용자의 쿠키정보, 세션ID, 민감한 정보 등을 탈취한다.
  • 2. CSRF(Cross-Site Request Forgery) 공격 : 사용자의 인증 정보를 이용하여 다른 사이트에 악의적인 요청을 보냄
    공격자가 다른 웹 사이트에서 사용자의 권한을 이용하여 악성 요청을 한다.(출금, 입금 등)
    이미 로그인되어 있는 상태에서 악성 스크립트(악성 페이지) 페이지를 클릭하여 이동하게 된다면 사용자의 쿠키정보, 세션ID 등 민감한 정보 등을 통하여 악성 요청을 보내게 되고 서버에서는 인증된 사용자로 판단하여 처리를 하게 된다.
  1. 하지만 내가 사용한 방법은 보안이 안되는 방식이였다. cookie에만 담아주면 된다고 생각했는데 쿠키도 값을 빼갈 수 있었고, httpOnly설정과, secure설정을 해주어야 했다. 그러면 XSS공격을 방어할 수 있다.
  2. 그리고 CSRF공격을 막기위해선 백엔드 서버쪽에서 Security설정하는 법도 있지만 프론트와 협업하여 CSRF 토큰을 통하여 2차 인증을 하는 방법이 있다고 한다.

2-2 액세스토큰 만료시 리프레시토큰 사용하여 갱신하기

  • axios 인터셉터를 사용하여 응답을 미리 받아와 처리를 할 수 있다.
  • 백엔드와 상태코드를 맞추어 사용자 권한이 필요한 요청시 액세스 토큰이 만료되어있다면 리프레시 토큰을 사용하여 다시 받아온다.
  • 액세스 토큰 만료시간을 짧게함으로 보안을 강화할 수 있다.

정리.

  1. 오어스는 직접적으로 사용자의 아이디와 비밀번호를 입력하지 않고 제 3자 애플리케이션에 서비스 권한만을 얻어와 보안부분에서 좋다고 판단했다.
  2. 가장 큰 이유로 요즘 많이 쓰이고 가입과 로그인이 쉽다는 점이 있다.
  3. 프론트에서 토큰등 개인 정보를 저장할때는 보안에 신경써야 하며,
    주의 해야할 보안중 XSS는 악성 스크립트를 사용하여 클라이언트를 공격하고, 개인정보 등을 탈취함으로 악성 동작을 하고, CSRF는 로그인이 완료된 상태에서 인증이 완료된 사용자 정보를 사용하여 서버를 타겟으로하여 악성 동작을 수행한다.
  4. 방어를 항상 생각해야하며, 방어 방법중 XSS는 HttpOnly쿠키로 접근하지 못하도록 방어하며, 이스케이프 처리를 하여 악성 스크립트를 심지 못하게 할 수 있으며, CSRF는 서버와 조율하여 CSRF토큰 방식을 추가하거나 다른 후속 처리를 할 수 있다.

참고 블로그

웹 보안 XSS, CSRF
프론트 안전하게 로그인 처리하기
inpa 오어스 정리

profile
초보 코딩

0개의 댓글