로그인

sally·2022년 6월 8일
2

프로젝트

목록 보기
3/5

세션 로그인/회원가입

세션과 쿠키 ,코드스쿼드 - 루카스 강의정리 (비밀😛))

  • 세션 : 로그인(인증) 이후, 사용자 별 정보 저장위한 자료구조 (메모리)
  • 쿠키 : 무상태의 HTTP 에서 서버에서 이용하는 사용자 식별 수단으로 브라우저에서 저장하는 값
    • 쿠키에 있는 session id 이용해서 서버가 클라이언트 식별, session_ db로부터 세션 정보 읽어 와서 인증, 인가 처리

logig/LoginService

  • 회원가입 - signup()
    • UserService - create 담당 (이미 존재하는 User 정보 검증 - UserService)
  • 로그인 - login()
    • 세션 값 ⭕ → 리턴(ok)
    • 세션 값 ❌ → 비밀번호 체크 후 로그인 & 세션에 담고 리턴(ok)
  • 로그아웃 - logout()
    • 세션 제거

HttpSession - setAttribute(name, value);

  • name : HttpSession의 여러 기능 중 내가 쓸 기능의 이름 정의

암호화

  • 양방향 : 복호화 가능 (대칭키, 공개키 방식)
  • 단방향 : 복호화 불가능 (해시함수)

패스워드 암호화 요구조건

  • 복호화 불가능 : 해시함수 사용
  • 하나의 패스워드 해시값이 노출되더라도, 다른 계정의 동일한 패스워드까지 탈취 당하면 안 된다.
    • salt 사용
    • ex. 동일 1234 -> 다른 해시값
  • Brute-force 공격 대비가 가능해야 한다.
    • 경우의 수를 무작정 투입해서 알아내려는 공격
      • 연산속도가 너무 빠르면 보안상 안 좋을 수 있다.
  • BCrypt 알고리즘 많이 사용

구현

  • Encryptor interface : 여러 암호화 모듈을 대비 interface로 상위 개념을 이용

  • strategy 패턴 : 인터페이스를 인자로 넘겨서 기능 위임

    • User 기능 테스트 하기가 편리해진다.

🟢 strategy 패턴: User with Encryptor

	@Transactional
	public Optional<User> findPasswordMatchingUser(String email, String password) {
		return userRepository.findByEmail(email)
			.map(user -> user.isMatched(encryptor, password) ? user : null);
	

Spring Security

스프링 생태계에서 인증, 인가 개념을 최대한 쉽고 유연하게 구현할 수 있게 만들어진 framework

  • 인증과 인가는 Spring Security의 궁극적으로 이루고자 하는 목표

인증

  • 사용자는 누구일까? - 나는 누구이며, 누구임을 증명한다
  • 한 번 의 로그인 후, 서비스 이용중에도 인증은 이루어 져야 한다.
    • user A 로그인 후, user B 의 서비스 요청에 대해 인증으로 구분한다.
  • 모든 요청 마다 인증을 해야 한다.
    • 방법1. 모든 요청마다 ID, PW를 포함시켜 요청한다.
    • 방법2. ID,PW 를 서버가 받으면, 난수형태의 KEY를 응답으로 전달하여, 요청마다 KEY를 포함한다.

인가

  • 당신은 무엇을 할 수 있습니까?
  • 인증 후, 리소스에 대한 권한 통제
    • 클라이언트 요청한 작업의 허가 여부 확인하는 절차
  • ex. 👺A가 😎B의 개인 정보/게시글/글쓰기 등 요청 → 인가 실패

세션

  • User A 로그인(인증)
    • 서버 : User 저장, 응답으로 JSESSIONID 반환
  • User A 는 JSESSIONID 저장 = 쿠키 저장
    • (로그인 이 후) 요청시 쿠키 전달
    • 서버 : 쿠키로 해당 세션을 찾고, 세션으로 Security Context 찾아 인증, 인가 거쳐 요청받은 리소스 반환

세션의 장점

  • 사용자 정보(세션)
  • JSESSIONID
    • 유의미한 값 X, 서버에서 세션 찾는 Key로만 활용
    • JSESSIONID 탈취 ≠ 개인정보 탈취
    • 세션하이제킹 공격은 주의

세션의 단점

  • 서버에 세션 저장 공간 필요
  • 분산 서버(클러스터 환경)에서 세션 공유 어려움
    • 세션 서버를 별도로 두거나 서버간 세션 공유 방법 등 사용
    • 하지만 쉬운 방법이 아니기에 토큰 이용

JWT

토큰으로 인증 하기, stateless
Json Web Token

Stateless

  • 세션의 단점 해결방안으로 사용
  • User A 로그인
    • 서버 : 토큰 생성 후 저장X, 응답으로 토큰 반환
  • User A 는 토큰 저장
    • (로그인 이 후) 요청시 토큰 전달
    • 분산환경에서 서버1 or 서버2 는 토큰을 의미 있는 값으로 해석 ➜ User A 인증

의미 있는 값

  • 세션 방식에서 JSESSIONID 는 의미있는 값이 아니다. (key 로만 활용)
  • 토큰은 유저를 설명할 수 있는 데이터를 포함 ➜ 의미 있는 값

토큰의 장점

  • 세션관리 할 필요가 없어 별도의 저장소가 필요하지 않다.
  • 서버 분산&클러스터 환경과 같은 확장성에 좋다.

토큰의 단점

  • 제공된 토큰의 회수가 어렵다.
    • 세션 : 서버에서 세션 삭제해서 브라우저의 JSESSIONID을 무용지물화
    • 토큰 : 서버에 저장하지 않기에 제공된 토큰 회수 할 수 없다.
      • 토큰이 한 번 생성 후, 저장하지 않기 때문에 삭제로 기존 토큰의 무용지물하는 등의 제어가 불가능
      • 토큰의 유효 기간을 짧게 한다.
        • ✔️토큰 만료 시간 필수
  • 토큰은 의미있는 데이터를 포함하기 때문에, 민감정보를 토큰에 포함시키면 안된다.
    • 패스워드, 개인정보 등 ❌

JWT 구조

① HEADER

  • JWT 검증에 필요한 정보 가진 객체
  • ③ SIGNATURE 에 사용한 암호화 알고리즘 정보, KEY의 ID 정보 담음
    • alg
    • kid(key id)
  • HEADER ➜ Json 변환 ➜ UTF-8 인코딩 ➜ Base64 URL-Safe 인코딩 한 값
  • 암호화 된 값은 아니다

② PAYLOAD

  • 인증에 필요한 데이터
    • Claim : 데이터 각각의 필드들 (다른 필드도 추가 가능)
      • sub : 대부분 username 포함 ➜ User 조회시 이용
      • iat : 토큰 발행 시간
      • exp : 토큰 만료 시간
  • PAYLOAD ➜ Json 변환 ➜ UTF-8 인코딩 ➜ Base64 인코딩 (변경한 데이터일뿐)
  • 암호화 ❌

③ SIGNATURE

  • JWT 토큰의 진위여부 판단 용도
  • 암호화 ⭕️: HEADER + PAYLOAD ➜ 비밀키(Secret Key)로 hashing ➜ Base64로 변경
    • HEADER와 PAYLOAD에 대한 보장
  • SecretKey : 절대 노출되선 안 된다.

Key Rolling

Secret Key를 여러개 둬서 Key 노출 대비

  • 수시로 추가/삭제하여 변경으로 노출되어도 다른 Secret Key와 데이터 안전하게 한다.

여러개의 Secret Key 존재
➜ Secret Key 1개에 unique 한 ID(①HEADER의 kid) 연결
➜ JWT 토큰 생성시 ①HEADER에 kid 포함
➜ 서버에서 토큰 해석시 kid 로 Secret Key 찾아 ③SIGNATURE 검증

Springboot 구현시 - ArgumentResolver

  • 스프링은 기본적으로 bean을 proxy 해서 다루고 있다.
  • MethodParamer : Controller의 parameter를 메타 정의 해 놓은

JWT (루카스)
json web token, rfc 7519 산업계 표준

  • 인증을 위한 방식이 아니다.
    • 두 장소 간 데이터를 안전하게 표현하고 교환하기 위한 방법
  • key 를 알아야만 위변조 가능
  • 수평 확장시 공유 할 게 없어서 좋다.
  • 보안에 좋은건 아니다.

OAuth 2

  • Authorization Server : 권한 관리 서버로 Access Token, Refresh Token 발급 및 관리
  • Resource Serve : Authorization Server와 관련하여 서비스 제공하는 서버
  • Resource Owner : 리소스(계정)의 주인 (계정 소유자 = 일반 사용자)
  • Client : Resource Owner 대리하여 리소스 요청하는 애플리케이션
  • AccessToken : Client로부터 Resource Owner 식별하기 위해 Authorization Server 발급 한 키
  • RefreshToken : Refreshing 하기위해 사용하는 키 (ex. AccessToken 만료 후 갱신 위해)

➕ 별도 정리한 🌵OAuth


Next. JWT와 OAuth2구현한 로그인 과정... one day...

  • 아래 참고내용 외에 Refresh Token, Access Token을 2개 같이 클라이언트로 보내는 것보다 다른 방법들을 알아보고, 개인적으로 구현
  • 틀린 내용이나 좋은 내용들 공유 해주시면 감사하겠습니다. 👍

참고

profile
sally의 법칙을 따르는 bug Duck

5개의 댓글

comment-user-thumbnail
2022년 7월 24일

로그인 쪽을 쭉 정리하고 계시는군요! 요악 잘하시네요~ 잘 읽고 갑니다 셀리~

1개의 답글
comment-user-thumbnail
2022년 7월 24일

로그인이 생각보다 더 쉽지 않은 녀석이었네요 ㅋㅋㅋㅋㅋㅋㅋ 잘 보고 가요 !!

1개의 답글
comment-user-thumbnail
2022년 7월 28일

로그인 구현했던게 다시 새록새록 떠오르고, 몰랐던 내용이 많아서 도움이 됐습니다 ㅎㅎ 잘봤어요 샐리리~~

답글 달기