현재 웹페이지들은 자동 로그인이나 로그인 기억하기 라는 이름으로 한 번 로그인하면 읠정 시간 동안 다시 로그인을 하지 않아도 되는 기능을 가지고 있다.
스프링 시큐리티의 경우 로그인기억 기능을 메모리상에서나 처리하거나, 데이터베이스를 이용하는 형태로 약간의 설정만으로 구현이 가능하다.
security-context.xml에는 <security:remember-me>태그를 이용해서 기능을 구현할 수 있다.!
해당 태그에는 아래와 같이 여러 속성값을 지정할 수 있다.
key | 쿠키에 사용되는 값을 암호화하기 위한(key)값 |
data-source-ref | DataSource를 지정하고 테이블을 이용해서 기존 로그인 정보를 기록(옵션) |
remember-me-cookie | 브라우저에 보관되는 쿠키의 이름을 지정한다. 기본값은 remember-me이다. |
remember-me-parameter | 웹 화면에서 로그인할 때 'remember-me'는 대부분 체크박스를 이용해서 처리한다. 이때 체크박스 태그는 name속성을 의미한다. |
token-validity-seconds | 쿠키의 유효시간을 지정합니다. |
DB를 이용하는 자동 로그인
우선 자동 로그인 기능을 처리하는 방식중 가장 많이 사용되는 방식 중 로그인이 되었던 정보를 DB에 이용해서 기록해 두었다가, 사용자의 재방문 시 세션에 정보가 없으면, DB를 조회해서 사용하는 방식이다.
서버의 메모리상에만 데이터를 저장하는 방식보다 좋은 점은 DB에 정보가 공유되기 때문에 좀 더 안정적으로 운영이 가능하다.
스프링 시큐리티에서 remember-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);
테이블을 생성하는 스크립트는 특정한 DB에 맞게 테이블 이름과 컬럼명을 제외한 컬럼의 타입 등을 적당히 조정해서
사용한다.
자동 로그인에서 DB를 이용하는 설정은 별도의 설정 없이 data-source-ref만을 지정하면 됩니다.
security-context.xml을 수정하자.
<bean id="customAccessDenied"
class="org.study.security.CustomAccessDeniedHandler"></bean>
<bean id="customLoginSuccess"
class="org.study.security.CustomLoginSuccessHandler"></bean>
<bean id="bcryptPasswordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
<bean id="customUserDetailsService"
class="org.study.security.CustomUserDetailsService"></bean>
<security:http>
<security:intercept-url pattern="/sample/all"
access="permitAll" />
<security:intercept-url
pattern="/sample/member" access="hasRole('ROLE_MEMBER')" />
<security:intercept-url pattern="/sample/admin"
access="hasRole('ROLE_ADMIN')" />
<security:access-denied-handler
ref="customAccessDenied" />
<security:form-login login-page="/customLogin"
authentication-success-handler-ref="customLoginSuccess" />
<security:logout logout-url="/customLogout"
invalidate-session="true" />
<security:remember-me
data-source-ref="dataSource" token-validity-seconds="2419200" />
<security:logout logout-url="/customLogout"
invalidate-session="true" delete-cookies="remember-me,JSESSION_ID" />
</security:http>
<security:authentication-manager>
<security:authentication-provider
user-service-ref="customUserDetailsService">
<security:password-encoder
ref="bcryptPasswordEncoder" />
</security:authentication-provider>
</security:authentication-manager>
</beans>
쿠키의 유효시간을 2419200으로 지정했다. (4주로 지정), 1주일이 604800이다.
로그인 화면에 자동 로그인을 설정할 수 있도록하겠다.
자동 로그인은 로그인 화면에서 선택해서 처리되므로, 체크박스의 형태로 구현,
인풋태그의 name속성값은 remember-me로 설정한다.
그리고 로그인화면을 담당하는 파일인 customLogin.jsp 폼태그 내에
<div>
<input type='checkbox' name='remember-me'> Remember Me
</div>
를 추가해 주었다. 프로젝트를 실행하여 확인해 보겠다.
리멤버미를 체크한 후 브라우저에서 쿠키를 조사해 보면 자동으로 리멤버미라는 쿠키가 생긴것을 알 수 있다.
그리고 DB에도 persistence_login테이블에도 사용자가 로그인한 정보가 남아 있는 것을 볼 수 있다.
리멤버 미 이름으로 생성된 쿠키는 유효기간이 있으므로, 사용자는 브라우저를 완전히 종료한 후에 다시 sample/admin과 같이 로그인이 필요한 페이지에
접근해 보면 정상적으로 로그인이 되어있는 것을 확인 할 수 있고, 브라우저가 보내는 정보를 확인해 보면
remember-me쿠키의 정보가 전송되는 것을 볼 수 있다.
로그아웃 시 쿠키 삭제
자동 로그인 기능을 이용하는 경우에 사용자가 로그아웃을 하면 기존과 달리 자동 로그인에 사용하는 쿠키도 삭제해 주도록
쿠키를 삭제하는 항목을 security-context.xml에 지정한다.
<security:http>
<security:intercept-url pattern="/sample/all"
access="permitAll" />
<security:intercept-url
pattern="/sample/member" access="hasRole('ROLE_MEMBER')" />
<security:intercept-url pattern="/sample/admin"
access="hasRole('ROLE_ADMIN')" />
<security:access-denied-handler
ref="customAccessDenied" />
<security:form-login login-page="/customLogin"
authentication-success-handler-ref="customLoginSuccess" />
<security:logout logout-url="/customLogout"
invalidate-session="true" />
<security:remember-me
data-source-ref="dataSource" token-validity-seconds="2419200" />
<security:logout logout-url="/customLogout"
invalidate-session="true" delete-cookies="remember-me,JSESSION_ID" />
</security:http>
별도의 설정이 없었다면 자동 로그인에서 사용한 쿠키의 이름은 리멤버미로 했었고, 톰캣을 통해 실행되고 있다면
was가 발행하는 쿠키의 이름은 JSESSION_ID이다. 톰캣 등이 발행하는 쿠키는 굳이 지정할 필요가 없지만
해당 모든 쿠키를 같이 삭제하는 것이 바람직하다.
아까 화면에서 로그아웃을 하였고
정상적인 로그아웃처리가된 화면을 확인했다.
아까의 라맴보마 쿠키가 사라져있는것을 볼 수 있다.
그리고 DB에도 삭제가 반영되어있음을 알 수가있다.
정말신기하게 쿼리문을 하나도 작성안했지만 생성 삭제가 되었다.
'Spring공부 > 4-스프링시큐리티' 카테고리의 다른 글
프로젝트(2) (0) | 2021.10.21 |
---|---|
프로젝트(1) (0) | 2021.10.21 |
스프링 시큐리티와 JSP (0) | 2021.10.19 |
커스텀 UserDetailsService (0) | 2021.10.19 |
JDBC를 이용하는 간편 인증/ 권한처리 (0) | 2021.10.18 |
댓글