자동로그인 기능은 대부분 쿠키(Cookie)
를 이용해서 구현된다.
스프링 시큐리티의 경우 remember-me
기능을 메모리상에서 처리하거나, 데이터베이스를 이용하는 형태로 약간의 설정만으로 구현이 가능하다. security-context.xml
에는 <security:remember-me>
태그를 이용해서 기능을 구현한다. <security:remember-me>
에는 여러 속성값을 지정할 수 있다. 여러 속성 중 주로 사용되는 속성은 이와 같다.
key
: 쿠키에 사용되는 값을 암호화하기 위한 키 값
data-source-ref
: DataSource
를 지정하고 테이블을 이용해서 기존 로그인 정보를 기록
remember-me-cookie
: 브라우저에서 보관되는 쿠키의 이름을 지정한다 .기본값은 remember-me
이다.
remember-me-parameter
: 웹 화면에서 로그인할 때 remember-me
는 대부분 체크박스를 이용해서 처리한다. 이 때 체크박스 태그는 name
속성을 의미한다.
token-validity-seconds
: 쿠키의 유효시간을 지정한다.
자동 로그인 기능을 처리하는 방식 중에서 가장 많이 사용되는 방식은 로그인이 되었던 정보를 데이터베이스를 이용해서 기록해 두었다가 사용자의 재방문 시 세션에 정보가 없으면 데이터베이스를 조회해서 사용하는 방식이다. 서버의 메모리상에만 데이터를 저장하는 방식보다 좋은 점은 데이터베이스에 정보가 공유되기 때문에 좀 더 안정적으로 운영이 가능하다.
스프링 시큐리티에서 remeber-me
기능 역시 JDBC
를 이용하는 경우처럼 지정된 이름의 테이블을 생성하면 지정된 SQL
문이 실행되면서 이를 처리하는 방식과 직접 구현하는 방식이 있다. 생성된 테이블은 로그인을 유지하는데 필요한 정보를 보관하는 용도일 뿐이니, 커스터마이징하기 보단 지정된 형식의 테이블을 생성한다.
스프링 시큐리티의 공식 문서에 나오는 로그인 정보를 유지하는 테이블은 아래와 같다.
create table persistent_logins
(
username varchar2(64) not null,
series varchar2(64) primary key,
token varchar2(64) not null,
last_used timestamp not null
);
테이블을 생성하는 스크립트는 특정한 데이터베이스에 맞게 테이블 이름과 컬럼명을 제외한 컬럼의 타입 등을 적당히 조정해서 사용하면 된다. 자동 로그인에서 데이터베이스를 이용하는 설정은 별도의 설정 없이 data-source-ref
만을 지정한다.
security-context.xml
<security:http>
<!-- 678p 자동 로그인(remember-me) token-validity-seconds=일주일 -->
<security:remember-me data-source-ref="dataSource" token-validity-seconds="604800"/>
</security:http>
자동 로그인은 로그인 화면에서 선택해서 처리되므로 체크박스 형태로 구현하고 <input>
태그의 name
속성값은 remember-me
로 지정한다.
customLogin.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>로그인 페이지</title>
</head>
<body>
<h1>커스텀 로그인 페이지</h1>
<h2><c:out value="${error}"/></h2>
<h2><c:out value="${logout}"/></h2>
<form action="/login" method="post">
<div>
<input type="text" name="username" value="">
</div>
<div>
<input type="password" name="password" value="">
</div>
<!-- 추가 -->
<div>
<input type="checkbox" name="remember-me">자동로그인
</div>
<div>
<input type="submit">
</div>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
</body>
</html>
프로젝트를 실행하고 자동로그인
을 체크한 후 브라우저에서 쿠키를 조사해 보면 자동으로 remember-me
라는 이름의 쿠키가 생긴다.
데이터베이스의 persistent_logins
테이블에도 사용자가 로그인한 정보가 남아있는지 볼 수 있다.
remember-me
이름으로 생성된 쿠키는 유효기간이 있기에, 사용자는 브라우저를 완전히 종료한 후 다시 /sample/admin
과 같이 로그인이 필요한 페이지에 접근해 보면 정상적으로 로그인 되는 것을 확인할 수 있다.
브라우저를 종료한 후 /sample/admin
을 호출했을 때, 브라우저가 보내는 정보를 확인하면 remember-me
쿠키의 정보가 전송되는 것을 볼 수 있다.
콘솔 해설
다시 접속한 사용자의 series를 찾아서 존재하면 자동 로그인한다. 그리고 다시 얻은 토큰과 로그인 시간을 업데이트한다.
자동 로그인 기능을 이용하는 경우에 사용자가 로그아웃을 하면 기존과 달리 자동 로그인에 사용하는 쿠키도 삭제해야 한다. 쿠키를 삭제하는 항목을 security-context.xml
에 지정한다.
security-context.xml
<security:http>
<!-- 681p 로그아웃할 때 쿠키도 삭제 -->
<security:logout logout-url="/customLogout" invalidate-session="true" delete-cookies="remember-me, JSESSION_ID"/>
</security:http>
별도의 설정이 없다면 자동 로그인에서 사용한 쿠키의 이름은 remember-me
였을 것이고 Tomcat
을 통해 실행되고 있었다면 WAS
가 발행하는 쿠키의 이름은 JSESSION_ID
였을 것이다. Tomcat
이 발행하는 쿠키는 굳이 지정할 필요는 없지만 관련된 모든 쿠키를 같이 삭제하는 것이 좋다.
다음 포스트는 해당 프로젝트에 어노테이션을 이용해서 스프링 시큐리티를 설정하는 방법에 대해서 포스트 할 것이다.