Hayden's Archive

[Spring] Spring Security에서 자동 로그인 구현하기 본문

Study/Java & Kotlin

[Spring] Spring Security에서 자동 로그인 구현하기

_hayden 2020. 11. 23. 09:45

요즘 Spring Legacy Project에 스프링 시큐리티를 적용하여 작업을 하고 있다.

SecurityConfig에 설정을 입력해서 암호화 후 DB에 회원 등록, 회원 로그인 및 로그아웃, 권한별로 페이지 접근 제한 및 스프링 시큐리티 태그 라이브러리 사용까지 완료하였다.

물론 중간중간에 시행착오와 삽질이 있었지만 그간 해보지 않았던 내용을 책과 구글의 도움을 받아 혼자서 배우고 익혀서 실습하고 성공했다는 데 보람을 느낀다.

스프링 시큐리티는 중간에 필터 하나 더 추가하는 것만으로 개발자가 인증 및 인가 절차를 편하게 구축할 수 있는 강력한 인터페이스를 제공해줘서 실제로 적용해보니까 이걸 왜 쓰는지 알겠다.

이제는 여기에 자동 로그인을 추가해볼까 한다.

나는 프로젝트에서 xml이 아닌 Java Config를 사용했으므로 Java Config 기준으로 추가해보겠다.

 


참고 : 

책 - 코드로 배우는 스프링 웹 프로젝트 ( book.naver.com/bookdb/book_detail.nhn?bid=13993776 )

 

 

자동 로그인은 영어로는 remeber-me 라고 하는데, 한번 로그인하면 일정 시간 동안 다시 로그인하지 않아도 된다. 

스프링 시큐리티에서는 이 기능을 메모리 상에서 처리 또는 데이터베이스를 이용하는 형태로 약간의 설정만으로 구현이 가능하다.

 

xml 에서는 <security:remember-me> 태그를 이용해서 기능을 구현한다. <security:remember-me> 의 속성값은 아래와 같다.

key : 쿠키에 사용되는 값을 암호화하기 위한 키(key)값
data-source-ref : DataSource를 지정하고 테이블을 이용해서 기존 로그인 정보를 기록(옵션)
remember-me-cookie : 브라우저에 보관되는 쿠키의 이름을 지정. 기본값은 'remember-me'
remember-me-parameter : 웹 화면에서 로그인할 때 'remember-me'는 대부분 체크박스를 이용해서 처리. 이 때 remember-me의 파라미터는 체크박스 태그는 name 속성을 의미
token-validity-seconds : 쿠키의 유효시간을 지정

 

위에서 말했듯이 remember-me 기능은 메모리상에서 처리하거나 데이터베이스를 이용하는데 나는 데이터베이스를 이용해서 자동 로그인을 구현해보겠다. 서버의 메모리상에만 데이터를 지정하는 것보다 훨씬 안정적이기 때문이다.

그러므로 로그인을 유지하는데 필요한 정보를 보관하는 용도로 DB 테이블을 만들어보겠다. 

스프링 시큐리티 레퍼런스 문서( docs.spring.io/spring-security/site/docs/5.4.1/reference/html5/ )에서는 아래와 같은 테이블 생성 예시를 제공하고 있다.

 

그대로 똑같이 만들어보겠다. 현재 PostgreSQL을 쓰고 있어서 PostgreSQL 기준으로 쿼리문을 작성했다.

CREATE TABLE persistent_logins (
	username text NOT NULL,
	series text PRIMARY KEY,
	token text NOT NULL,
	last_used timestamp NOT NULL
 );

 

DB 테이블까지 완성된 것을 확인!

 

이제 ServletConfig.java에 설정을 해준다.

먼저 미리 등록해둔 DataSource Bean을 autowired하고,

@Autowired
@Qualifier("dataSource")
private DataSource dataSource;

 

PersistentTokenRepository에 DataSource 설정을 지정해주고 리턴하는 메소드를 작성한다.

@Bean
public PersistentTokenRepository persistentTokenRepository() {
	JdbcTokenRepositoryImpl repo = new JdbcTokenRepositoryImpl();
	repo.setDataSource(dataSource);
	return repo;
}

 

이제 Override된 configure 메소드에 자동 로그인과 로그 아웃시 쿠키 삭제를 입력해준다.

/* 자동 로그인 설정 */
http.rememberMe()
  .key("hayden") //쿠키에 사용되는 값을 암호화하기 위한 키(key)값
  .tokenRepository(persistentTokenRepository()) //DataSource 추가
  .tokenValiditySeconds(604800); //토큰 유지 시간(초단위) - 일주일

/* 로그아웃 설정 */
http.logout()
  .logoutUrl("/logout")
  .logoutSuccessUrl("/")
  .invalidateHttpSession(true) //세션 삭제
  .deleteCookies("remember-me", "JSESSIONID"); //자동 로그인 쿠키, Tomcat이 발급한 세션 유지 쿠키 삭제

 

 

이제 로그인 화면으로 가서 자동 로그인 체크박스의 이름을 정해준다. 위에서 따로 정해주지 않았으므로 기본 이름인 remember-me를 지정해주면 된다.

나는 로그인을 form으로 제출했지만, 만약 ajax로 처리하는 경우 넘겨주는 파라미터를 remember-me로 하여 체크 값을 함께 넘겨주면 된다.

 

 

그리고 나서 로그인 해보면 이렇게 DB에 사용자가 로그인한 정보가 잘 들어와있는 걸 확인할 수 있다.

 

크롬에서 F12를 누르고 Application - Storage - Cookies 에서 확인해보면 remember-me 쿠키도 잘 들어온 걸 알 수 있다.

 

 

그리고 나서 로그아웃 해보면 DB에 있던 사용자가 로그인한 정보와 자동 로그인 쿠키가 감쪽같이 사라진 것을 확인할 수 있다~!