티스토리 뷰

저번장에는 Security의 기본세팅에 대해 정리해보았는데 이번에는 Security에서 제공해주는 Remember-me이 무엇인지 알아보자.
Spring으로 웹개발을 하면서 자동로그인 기능을 구현할 때가 있다. 그때 Security에서 제공해주는 Remember-me가 있다.
이 기능을 활용하면 쉽고 간단하게 자동로그인을 구현할 수 있는데 이번장에서 예제코드와 구현시 주의사항에 대해 알아보자.

로그인 폼에 자동로그인 checkbox 생성

다음과 같이 로그인 폼에 name='remember-me' 라는 checkbox를 추가하였다.

 

 

자동로그인 기능을 활용하기위해 checkbox에는 정해진 value값을 세팅해줘야한다. 위와 같은 파라미터값이

존재하지않으면 자동로그인을 체크한 뒤 로그인을 해도 유지가 되지않는다는점 주의하자

 

참고로 value값에 아무런 값도 세팅이 되지않으면 'on' 이라는 값이 전송된다.

Security Config에 remember-me 관련설정 추가

Line 59 : RememberMe 설정을 추가한다.
Line 60 : 인증받은 사용자의 정보로 token을 생성하는데 사용되는 key값을 설정한다. (임의 값 설정)
Line 61 : token을 생성하기 위한 파라미터이다 (자동로그인의 checkbox).
Line 62 : 생성된 token의 만료시간을 정한다.

여기서 주의할점은 form안에 있는 checkbox의 name값이 rememberMeParameter() 메서드 인자에 선언된 값과 동일해야한다.

자동로그인 테스트

자동로그인을 check하고 로그인뒤 개발자 도구의 Application 탭에 Cookie항목을 클릭하면 'remember-me'라는 cookie이름으로
token이 생성되었다. 그리고 다시 브라우저를 닫고 새 브라우저를 연 상태에서 login페이지가 아닌 인증된 사용자만 접근할 수 있는 요청을 url 입력창에다 바로 입력해서 요청하면 login페이지가 아닌 요청된 페이지로 이동하게 된다.

만약 자동로그인이 정상적으로 되지않는다면 필자가 작성하는 글을 계속 읽어주길 바란다.

과연 이 RememberMe는 어떻게 동작하는 것일까?

동작원리

RemeberMe 설정을 추가하게되면 RememberMeAuthenticationFilter가 작동하게 된다.
Line 97을 보게되면 SecurityContextHolder에서 인증된 사용자의 정보를 꺼내서 인증된 사용자가 존재하지 않으면
Line 104의 authLogin() 메서드를 호출한다. authLogin()는 RememberMeServices 인터페이스의 메소드이다.



RememberMeServices 인터페이스의 구현체인 AbstractRememberMeServices에서 authLogin()을 오버라이딩하여 자동로그인 로직을 처리하게 된다.
그리고 설정파일에서 rememberMeParameter() 값을 세팅해주었는데 이 값을 세팅하지않으면 'remember-me'가 default값이 된다.
cookie이름도 config 파일에서 임의로 지정할 수 있으며 default값은 parameter와 같은 'remember-me'가 된다.
위 사진의 좌측에 빨간색 테두리와, 파란색 테두리를 유심히 봐두자.



먼저 request객체에 cookie값들을 for문을 통해 'remember-me'의 이름을 가진 cookie의 value값을 리턴한다.
해당 값은 사용자의 정보로 만들어진 token 값이다.



token값을 decoding 하여 token값을 얻어온다.



AbstractRememberMeServices의 하위클래스인 TokenBasedRememberMeServices에서 decoding한 token을 검증한다.
token의 만료시간을 체크하고 token에서 사용자 ID를 가져와 DB에서 사용자정보를 조회한다.

token의 만료시간과 사용자ID, 사용자 패스워드 그리고 token을 생성하기 위한 key 총 4개로 token을 생성하는데
해당 token은 만료기간까지 유효하며 중간에 비밀번호가 변경이 되버리면 Line 116의 Exception이 발생하게 된다.



그리고 해당 사용자의 (UserDetails 인터페이스를 구현한 사용자 정보가 담긴 모델객체) 계정상태를 체크한다.
첫째 isAccountNonLocked : 계정이 잠겨있는지 아닌지를 리턴한다 (false : 잠긴계정)
둘째 isEnabled : 해당계정이 사용가능한지 여부를 리턴한다 (false : 사용이 불가능한 계정)
셋째 isAccountNonExpired : 계정이 만료되었는지 아닌지를 리턴한다 (false : 만료된 계정)
넷째 isCredentialsNonExpired : 계정의 패스워드가 만료되었는지 리턴한다 (false : 만료된 패스워드)

 

4가지의 상태여부중 하나라도 false가 리턴되면 로그인이 되지않음을 알 수 있다.

이 부분은 잠시후 테스트를 통해 알아보자



인증로직이 모두 정상적으로 이뤄지면 RememberMeAuthenticationFilter에서 SecuriContextHolder에 인증이 완료된
Authentication객체를 세션에 저장함으로써 브라우저를 종료후 새 브라우저에서 인증된 사용자만 접근할 수 있는 페이지로 요청해도 로그인페이지로 이동되지 않음을 알 수 있다.

 

위에서 테스트를 해보겠다고 한 것이 있는데 지금 한번 테스트를 시도해보자.

사용자 상태변경에 따른 자동로그인 테스트

 

 

 

사용자의 상태를 하나씩 체크를 해보니 상태를 관리하는 메서드가 하나라도 false를 리턴하면 자동로그인이 되지않는점을 알 수 있었다.

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함