Giter Site home page Giter Site logo

로그인 상태 구현 about racket HOT 4 OPEN

suyeon0 avatar suyeon0 commented on July 28, 2024
로그인 상태 구현

from racket.

Comments (4)

suyeon0 avatar suyeon0 commented on July 28, 2024

1. 쿠키&세션이 필요한 이유

  • HTTP 특징 - stateless
    • HTTP 는 먼저 클라이언트가 request 를 서버에 보내면, 서버는 클라이언트에게 요청에 맞는 response 를 보내고 접속을 끊는 특성이 있다
    • 헤더에 keep-alive 라는 값을 줘서 커넥션을 재활용
    • stateless 로 설계 해도 되는 서비스가 있고 상태를 유지해야하는 서비스도 있다. (무상태 예시 - 로그인 필요 없는 단순한 서비스 소개 화면 / 상태유지 예시 - 로그인한 사용자의 경우 로그인 했다는 상태를 서버에 유지)

2. 쿠키

  • 클라이언트(브라우저) 로컬에 저장되는 key-value 형태의 작은 데이터 파일 (-> 브라우저에 종속적)
  • 라이프사이클
    • (1) 세션 쿠키 : 현재 세션이 끝날 때 삭제
    • (2) 영속 쿠키 : 브라우저가 종료 되어도 만료되지 않고 유지 (Expires, Max-age)
  • 생성
    • HTTP Response 헤더의 set-cookie 속성을 사용하여 생성
    • 브라우저가 이를 응답으로 받아서 로컬에 저장하고, Request Header 에 넣어서 자동으로 서버에 전송
  • 구성 요소
    • 이름, 값, 유효시간, 도메인, 경로
  • 도메인
    • 쿠키는 도메인에 종속적(생성된 도메인에서만 유효. 다른 도메인에서는 엑세스 불가)
      • 보안 및 개인 정보 보호를 강화하기 위함
      • CORS 방식 (여러 도메인에 request 를 보내는 브라우저) 를 사용할 땐 쿠키 및 세션 관리가 어려워진다

3. 세션

  • 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리, 세션은 서버 측에서 관리
    • 쿠키보다 보안에 좋지만, 서버 자원을 사용하는 것
  • 세션 종료 시점
    • application 종료
    • 타임아웃(timeout)
    • session 객체(object)의 invalidate() 호출
  • 서버에서는 클라이언트를 구분하기 위해 세션ID 를 부여
    • 사용자 정보는 DB 에만 있고, 클라이언트(쿠키)와 서버는 세션 ID 만 사용하여 인증 확인
    • 서버가 클라이언트 ID를 어떤 방법으로 추적할 것인지 정의한 것을 세션 트래킹 모드 라고 합니다. 트래킹 모드에는 /쿠키 사용 모드, URL Rewriting 모드, SSL 모드/ 가 있는데 대부분 서버에서 쿠키 사용 모드를 기본값 으로 하고 있고 이 모드 사용을 권장 하고 있습니다. 그래서 특별한 설정이 없으면 클라이언트를 구분하기 위해 쿠키 를 활용하는 것입니다.
      세션 동작 원리 - 쿠키와 세션의 관계

4. HttpSession

  • AsIs
    • SessionManager 스프링 빈을 따로 만들어서, 세션의 기능(생성, 조회, 만료처리) 을 구현
    • static ConcurrentMap 으로 세션 데이터 저장
  • ToBe. 동일한 역할을 하는 HttpSession 객체를 사용하도록 수정
    • client request에서 client를 식별하고, 해당 client 정보를 저장하는 방법을 제공하는 Java의 public interface
    • 세션 생성 : httpServletRequest.getSession()
    • JSESSIONID
      • 톰캣 컨테이너에서 세션을 유지하기 위해 발급하는 키
      • Map<SessionStorageKey, SessionStorage> -> Map<JSESSIONID, Map<AttrubiteKey, Value>>
    • "loginUser"(key):SessionUser(val) 세팅

5. 세션 저장 방식

  • 메모리 - was 재구동시 쿠키에는 세션ID 가 남아있지만 세션(서버)은 초기화. 용량 문제. was N대
  • DB
    • 여러개의 서버로 운영할 때 클라이언트가 어떤 서버로 접속했든 로그인 상태를 유지하려면(세션동기화가 필요하다면), DB 에 세션 정보를 넣을 필요가 있다
    • 세션 확인할 때마다 매번 DB I/O가 발생하므로, 메모리 DB 인 Redis 를 사용

6. Session Redis 연동

implementation(“org.springframework.session:spring-session-data-redis”)

6-1. Spring Session

* 스프링 프레임워크에서 제공하는 모듈. 외부 저장 매체를 이용해서 여러 서버의 session을 쉽게 동기화 할 수 있다
* https://spring.io/projects/spring-session

6-2. 기존 사용하던 application container 에서 제공하는 HttpSession 과의 차이점

  • application container 의 HttpSession 을 사용할 땐 WAS 에서 세션을 관리했다. 세션 공유 문제를 해결하기 위한 방법 중 세션 정보를 서버가 아닌 다른 외부 저장소에 저장하는 방법 (Session Server) 이 있는데,
  • spring session 은 외부 저장소와의 HttpSession 연동을 간단한 구현으로 가능하게끔 지원해준다

6-3. Spring Session 을 사용했을 때, Tomcat이 만들어낸 JSESSIONID 쿠키가 없어지는 이유

  • Spring Session 필터가 먼저 적용되기 때문(세션은 필터, 서블릿에서 getSession 으로 세션을 요청할 때 처음 생성되는 것 기억)

6-4. 동작 내용

* 1. 세션 생성 : 클라이언트가 서버에 최초로 요청을 보내면 Spring Session 이 새로운 세션을 생성한다. 이 때 SessionId 가 생성되고 클라이언트에 응답으로 전달됨
* 2. 세션 저장 : 서버는 세션 데이터를 메모리나 DB 등에 저장한다. 기본적으로 서블릿 컨테이너의 메모리에 저장
* 3. 세션 식별자 전달 : 클라이언트는 세션 식별자를 쿠키 등을 통해 서버에 전달.
* 4. 세션 조회 및 수정 : 레디스를 사용했다면 세션 식별자로 레디스를 조회
* 5. 세션 만료 : 세션의 만료여부를 확인하고 자동으로 제거

7. 로그인 상태 체크 인터셉터 개발

  • 필터가 아닌 인터셉터를 사용한 이유
    • 필터는 스프링 컨텍스트 외부에 존재해서 공통된 보안 및 인증/인가 관련 작업,
      모든 요청에 대한 로깅 또는 체크에 관련한 작업이 적합
    • 인터셉터는 Dispatcher Servlet 이 Controller 를 호출하기 전/후 작업이므로 로그인과 같은 권한 체크는 인터셉터가 적합하다고 판단.

from racket.

suyeon0 avatar suyeon0 commented on July 28, 2024

2023.05.24 코드 리뷰 반영

  1. VO 클래스명 수정 (~VO)
  2. 메소드명은 isNot 보다는 is 가 가독성이 좋다
  3. 컨트롤러 리턴 타입을 NULL 로 만들지 말자. 무조건 값이 있거나 Exception 이 발생하거나
  4. globalAdvice 는 순차적으로 적용된다는 것을 기억해놓자
  5. CustomException 은 RuntimeException 을 상속받도록
  6. 테스트 코드 보완 -> 다양한 파라미터 테스트 가능하도록 수정 (@ParameterizedTest, @valuesource 사용)
  7. 패키지 구조 수정
    ---- api 패키지 : @RestController
    ---- view 패키지 :@controller
    ----- auth
    ------ auth.login
    ----- home
  8. @transactional 클래스 단위가 아니라 메소드 단위로
  9. Redis 만료시간은 "짧게" 지정. 만료 시간을 지정하지 않아 계속 남아있게 되어 운영 장애로 발생하는 경우가 있다
  10. data Class 를 작성할 때는 이 필드가 필수값인지 선택값인지 잘 생각해보고 작성하자
  11. Enum 은 클래스명에 Type 을 붙인다
  12. 외부 API 호출 구간에 "캐시" 를 사용하는 것이 좋다

from racket.

suyeon0 avatar suyeon0 commented on July 28, 2024

2023.06.08 코드리뷰 반영

  1. 로그인 체크는 인터셉터보다 필터가 적합 (Spring Container 외부 로직이므로)
  • 인터셉터가 적합한 예제 : UserAgent 를 가공하는 작업 등
  • 유저 권한 확인 적합 : AOP
  1. 코틀린 리팩토링
  • if/else 자체가 하나의 expression 임을 기억하기. 이거 자체를 리턴하면 됨
  1. DB 조회할 땐 항상 Optional 을 리턴하고 orElseThrow 나 isPresent 를 사용하자

  2. 로그인 체크 함수에서 동일한 DB 조회를 2번 하는 로직 수정하기

  3. 이메일 중복 체크 Boolean 으로 변경하기 & DB 조회 1번으로 줄이기

  4. view Controller 와 api Controller 구분하기

  5. login 호출시 request param 호출 하는 부분은 POST Json Body 로 바꾼다.

from racket.

suyeon0 avatar suyeon0 commented on July 28, 2024

2023.06.14 코드 리뷰

  1. advice
  • RestController, Controller 구분
  • Exception -> RuntimeException
  • @order 로 적용되는 advice 순서를 지정할 수 있다
  • RuntimeException 은 globalAdvice - Order 기본값 에서 다루는 것이 좋을 것 같다
  1. @target
  • 해당 사용자가 만든 어노테이션이 적용될 수 있는 타입을 지정
  • @target({ElementType.XXXX, ElementType.XXXX,....})
  • ElementType.TYPE : Class, interface (including annotation interface), enum, or record declaration
  • ElementType.METHOD : Method declaration
  1. @throws 을 사용하는 것이 아니라 exception 이 발생할 곳과 처리 내용을 명시적으로 표기하기
    ex. @Throws(IOException::class, ServletException::class)

  2. filter 는 OncePerRequestFilter 를 사용

  3. 유저 정보를 쿠키나 세션에 넣는 것은 보안 위험이 존재. 따라서 암호화해서 넣어야 함. OR 모든 api 에서 유저 정보를 필요로 하지는 않을 것. 따라서 쿠키에는 sessionId 만 넣어놓고 필요할 때마다 Redis 를 조회하는 것도 방법.

  4. 세션 만료시 catch 코드 수정 필요. view 와 api 각각에 대해 따로 처리가 필요.

  5. @qualifier

- 스프링에서 만약 동일한 타입을 가진 bean 객체가 두 개 이상일 때 스프링은 컨테이너를 초기화 하는 과정에서 Exception 을 발생시킨다. 이 문제를 해결하기 위해 @Qualifier 를 사용한다

- 사용할 특정 객체를 찾기 위한 이름을 지정한다

from racket.

Related Issues (9)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.