처음부터 차근차근

spring security 사용해서 로그인 유지 기능 만들기 본문

Framework/Spring

spring security 사용해서 로그인 유지 기능 만들기

_soyoung 2022. 12. 11. 19:30
반응형

개요

예시 : 네이버 로그인 유지 기능

위의 이미지는 로그인 유지 기능 예시 이미지이다.

spring security를 이용하면 위와 같은 로그인 유지 기능을 쉽고 빠르게 만들 수 있다.

 

spring security의 세션 유효시간은 15분이다. 

그래서 로그인을 한 후 15분이 지나면 세션이 만료되어 로그아웃 처리된다. 

그래서 15분 후에도 로그인을 유지하고 싶으면 로그인 유지 기능을 따로 만들어야하는데,

spring security에서는 로그인 유지 기능을 rememberMe라는 쿠키를 이용해서 암호화된 키값을 저장하는 방법으로 로그인 유지 기능 만드는 것을 제공하고 있다.

 

 

로그인을 유지하는 방법 3가지

1. 로그인 할 때 유저의 아이디, 비번, 만료시간, 키 등을 쿠키로 저장해 놓는 방법

이 방법은 보안적으로 매우 좋지 않다.

해커가 이 쿠키만 탈취하면 해당 계정은 공공재가 되기 때문이다.

 

2. "아이디 + 토큰" 문자열을 암호화해서 쿠키로 저장해 놓는 방법

여기서 토큰은 랜덤한 문자열이다.

토큰 값은 로그인(인증)할 때마다 바뀐다.

아이디와 토큰을 합해 암호화해서 rememberMe 쿠키로 저장해 놓으면 해커가 쿠키를 탈취해도 복호화 하지 못하는 이상 계정을 사용할 수 없다.

하지만 완벽한 것 같은 이 방법에는 단점이 존재한다.

해커가 먼저 쿠키로 로그인(인증)한 경우 토큰 값이 바뀌어버리기 때문에

원래 계정 주인이 로그인하게 되면 유효하지 않은 토큰값으로 로그인하는게 되어버려 로그인을 못하게 된다.

그래서 이 문제점을 보완한 방법이 3번째 방법이다.

 

3. "아이디 + 토큰 + series" 문자열을 암호화해서 쿠키로 저장하는 방법

 series 값을 뒤에다 추가해서 아이디, 토큰 값과 함께 rememberMe 쿠키로 저장한다.

여기서 series는 사용자가 처음 로그인할 때 생성되는 랜덤한 고정 값이다.

이렇게하면 series 값으로 인해 계정이 구분이 되서 해커가 로그인한 다음에 원래 계정 주인이 로그인하게 될 시, 

아이디, 유효하지 않은 토큰값, 유효한 series값으로 인증 요청을 하게되는데, 이럴 경우 모든 토큰을 삭제해서 유효하지 않게 만들고 둘 다 로그아웃 시켜버린다. 그러면 원래 계정 주인은 form을 통해 다시 로그인을 하면 된다.

그러면 또 새로운 토큰값을 생성하게 될테고, 해커는 다시 또 그 토큰을 찾아야만 로그인 할 수 있다.

 

 

spring security 이용해서 로그인 유지 기능 만들기

제일 안전한 3번 방법으로 로그인 유지 기능을 만들었다.

이 방법은 series 값을 고정으로 기억하고 있어야 하기 때문에 db에다 저장하는 과정을 한 번 거쳐야 한다.

그래서 제일 먼저 테이블을 만들어줘야 한다.

 

1. persistent_logins 엔티티 생성

@Table(name = "persistent_logins")
@Getter
@Setter
@Entity
public class PersistentLogins {

    @Id
    @Column(length = 64)
    private String series;

    @Column(nullable = false, length = 64)
    private String username;

    @Column(nullable = false, length = 64)
    private String token;

    @Column(name = "last_used", nullable = false, length = 64)
    private LocalDateTime lastUsed;
}

 

2. html 폼 수정

<div class="checkbox-content">
    <input type="checkbox" id="rememberMe" name="remember-me">
    <label for="rememberMe" class="text">로그인 유지</label>
</div>

check box의 name 값을 반드시 remember-me로 지정해줘야 한다.

 

3. spring security 설정 파일에다 내용 추가

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig {
    private final LoginService loginService; // UserDetailsService 구현체
    private final DataSource dataSource;

    @Bean
    public PersistentTokenRepository tokenRepository() {
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        jdbcTokenRepository.setDataSource(dataSource);

        return jdbcTokenRepository;
    }
    
    @Bean
    public SecurityFilterChain configure(HttpSecurity http) throws Exception {
    	... 생략
    
    	// 로그인 유지
        http
        		.rememberMe()
                .userDetailsService(loginService)
                .tokenRepository(tokenRepository()); // username, 토큰, 시리즈를 조합한 토큰 정보를 DB에 저장

        return http.build();
    }
    ... 생략
}

 

결과

로그인 유지 체크 시

로그인 유지 체크박스에 체크하고 로그인하면 persistent_logins 테이블에 series와 토큰, 아이디가 저장된 것을 볼 수 있다.

로그아웃 시

로그아웃 하면 데이터가 모두 삭제된다.

 

 

참고 : https://jaimemin.tistory.com/2079

반응형
Comments