종우의 삶 (전체 공개)

Spring security - 5 // 로그인 기능 구현 본문

개발/Spring

Spring security - 5 // 로그인 기능 구현

jonggae 2024. 1. 29. 15:35

대상 Repository : https://github.com/Jonggae/security

Security와 관련된 내용들을 연습한다.


목표 기능

1. H2 인메모리 DB를 이용한 회원가입 데이터의 저장

-> 사용자는 회원가입 과정에서 username, password, email을 입력하며, password는 암호화되어 DB저장 된다. 연습 프로젝트이므로 인메모리 데이터베이스를 이용하여 쉽게 휘발되는 데이터 저장을 진행한다.

 

2. 회원가입 후 로그인

-> 회원가입후 로그인을 하려면 인증에 필요한 토큰을 발급받아야 한다. Spring security를 이용하여 로그인 과정을 구현한다. username 과 password를 서버에 전송하면 DB내에서 올바른 정보인지 확인한 후, Jwt토큰을 발급한다. 

bearer 헤더로 담아온 jwt토큰을 확인하여 회원 정보, 회원의 접근 권한등을 확인한다. 

 

ROLE_USER,

ROLE_ADMIN 2개의 권한을 사용한다. 

 

USER와 ADMIN은 서로 접근할 수 있는 uri가 다르게 설정한다 (ADMIN은 현재 큰 기능이 없음)

 

3. (부가목표) Postman으로 테스트를 진행한 후에 문제가 없으면 간단한 프론트페이지를 만들어 홈페이지를 구성해본다.

-> 

회원 가입 페이지

로그인 페이지

회원 별로 다르게 출력되는 동적페이지 구성 ( {username}님 환영합니다 같은 문구 )


 

회원 가입 자체는 앞서 적었던 포스트에서 확인할 수 있듯 비교적 간단하게 구현이 가능하다.

단순히 UserService 내에서 데이터를 DB에 저장만 하면 되는 것이었다. 하지만 Security를 무시하면 안된다.

이때까지 간단할줄로만 알았던 로그인 인증 / 인가 과정이 남아있었다.

 

처음의 내 생각은 그냥 로그인 과정에서 입력한 정보가 DB의 값과 같으면 로그인이 완료되는 줄로만 알았다. 그래서 회원가입을 했던 것 처럼 소소하게 view 페이지를 만들고 로그인을 하려고했는데.. 

 

저 "DB의 값과 같으면" 이라는 말이 그리 단순한 것이 아니었다.

 

그 안에는 '인증'이라는 개념이 들어가있었고, 앞서 작성한 Security의 전체 프로세스를 다 이해하고 있어야 하는 것이었다.

https://jonggae.tistory.com/126

 

 

다시 간단히 정리해보자면, 

 

1. 회원 가입이 완료되면 서버 DB에는 회원의 정보가 저장된다.

 

2. 그 회원이 로그인을 시도하면, 서버에서 그 정보를 확인한 후 접근 허가를 내준다. 

 -> Authentication, Authority. 인증, 인가와 관련된 내용.

이러한 과정이 암호화되지 않은 password, 인증 토큰들을 사용하여 진행된다면 보안성이 굉장히 취약해지고 의미없는 기능이 될 것이다. 그래서 쿠키, 세션같은 기능을 사용하여 사용자를 식별하고 안정적인 서비스를 사용할 수 있게 만드는 것이다.

 

정보가 클라이언트(사용자) 쪽에 저장되는 쿠키

서버 쪽에 저장되는 세션은 본 프로젝트에서 사용하지 않았으므로 따로 언급하지 않는다.

 

나는 몇번 얼추 사용해본 적있는 JWT를 선택하였다.

 

JWT (Json Web Token)

Jwt는 웹 개발에서 인증 및 정보 교환을 위한 토큰 기반의 인증 방식이다.

 

Header, Payload, Signature 등으로 구성되어 있다.

 

Header : JWT의 타입과 사용하는 해시 알고리즘등의 메타 정보가 포함된다.

Payload: 실제로 전송할 정보가 포함되며, Claim 이라고 부르는 특정한 정보를 포함할 수 있다.

Signature: Header와 Payload를 합친 후, Secret Key를 사용하여 서명된 부분으로 토큰이 변조되지 않음을 검증한다.

 

동작 방식

1. 인증

사용자가 로그인을 시도하면 서버는 사용자의 정보를 DB에서 확인하고, 유효한 경우 JWT를 발급한다.

발급된 JWT는 클라이언트(사용자)에게 전달되고, 클라이언트는 이를 저장하여 이후 요청에 사용한다.

 

2. 토큰 전송

클라이언트는 JWT를 HTTP 헤더에 실어 서버에게 요청을 보낸다. 

일반적으로 Authorization 헤더에 Bearer 스킴을 사용한다. ("Bearer " 같이 공백을 포함하여 전송)

 

3. 검증

서버는 수신한 JWT의 서명을 확인하여 토큰의 유효성을 검증한다. 

유효한 토큰이라면 서버는 해당 요청에 대한 권한을 부여하고, 클라이언트에게 응답해준다.

 

무상태, 분산시스템을 이용한 확장 용이, 추가적인 서버 조회가 없이 정보를 해석할 수 있는 특징이 있다.

 

실제로 JWT를 어떻게 발급하고, 서버 입장에서 확용할 수 있을까? 

 

코드와 함께 살펴보도록 하자. 계속.


 

Comments