본문 바로가기
스프링과 JPA 기반 웹 어플리케이션 개발/1부 (개발환경, 회원가입, 로그인, 계정설정)

19. 로그인 기억하기(RememberMe)

by Backchus 2020. 4. 21.

세션이 만료 되더라도 로그인을 유지하고 싶을 때 사용하는 방법

  • 쿠키에 인증 정보를 남겨두고 세션이 만료 됐을 때에는 쿠키에 남아있는 정보로 인증한다.

해시 기반의 쿠키(SpringSecurity제공)

  • Username
  • Password
  • 만료 기간
  • Key(애플리케이션 마다 다른 값을 줘야 한다.)
  • 치명적인 단점, 쿠키를 다른 사람이 가져가면... 그 계정은 탈취당한 것과 같다.

조금 더 안전한 방법은?

  • 쿠키안에 랜덤한 문자열(토큰)을 만들어 같이 저장하고 매번 인증할 때마다 바꾼다.
  • Username, 토큰
  • 문제는 이방법도 취약하다. 쿠키를 탈취 다하면, 해커가 쿠키로 인증을 할 수 있고, 희생자는 쿠키로 인증하지 못한다.

조금 더 개선한 방법(SpringSecurity제공)

  • https://www.programering.com/a/MDO0MzMwATA.html
  • Username, 토큰(랜덤, 매번 바뀜), 시리즈(랜덤, 고정)
  • 쿠키를 탈취 당한 경우, 희생자는 유효하지 않은 토큰유효한 시리즈와 Username으로 접속하게 된다.
  • 이 경우, 모든 토큰을 삭제하여 해커가 더이상 탈취한 쿠키를 사용하지 못하도록 방지할 수 있다.

스프링 시큐리티 설정: 해시 기반 설정

http.rememberMe().key("랜덤한 키 값")

 

스프링 시큐리티 설정: 보다 안전한 영속화 기반 설정

SecurityConfig에 설정 추가

package me.weekbelt.studyolle.config;

@RequiredArgsConstructor
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final AccountService accountService;
    private final DataSource dataSource;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        
        // 기존 코드 ........

        http.rememberMe()
                .userDetailsService(accountService)
                .tokenRepository(tokenRepository())
        ;
    }

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

    // 기존 코드 .....
}

 

JdbcTokenRepositoryImpl클래스에 필드로 선언된 이 쿼리에 해당하는 persistent_logins엔티티 생성

public static final String CREATE_TABLE_SQL = "create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null)";
package me.weekbelt.studyolle.domain;

@Table(name = "persistent_logins")
@Entity
@Getter @Setter
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;
}

 

login.html에 로그인 유지 체크 박스 추가

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org">
<!--head-->
<head th:replace="fragments.html::head"></head>

<body class="bg-light">
<!--네비게이션 바-->
<div th:replace="fragments.html::main-nav"></div>


<div class="container">
    <div class="py-5 text-center">
        <p class="lead">스터디올래</p>
        <h2>로그인</h2>
    </div>
    <div class="row justify-content-center">
        <div th:if="${param.error}" class="alert alert-danger" role="alert">
            <p>이메일(또는 닉네임)과 패스워드가 정확하지 않습니다.</p>
            <p>또는 확인 되지 않은 이메일을 사용했습니다. 이메일을 확인해 주세요.</p>
            <p>
                확인 후 다시 입력하시거나, <a href="#" th:href="@{/find-password}">패스워드 찾기</a>를 이용하세요.
            </p>
        </div>

        <form class="needs-validation col-sm-6" action="#" th:action="@{/login}" method="post" novalidate>
            
            // 기존 코드 .....

            <div class="form-group form-check">
                <input type="checkbox" class="form-check-input" id="rememberMe" name="remember-me" checked>
                <label class="form-check-label" for="rememberMe" aria-describedby="rememberMeHelp">로그인 유지</label>
           </div>

            // 기존 코드 .....
        </form>
    </div>
    <!-- footer -->
    <div th:replace="fragments.html::footer"></div>
</div>
<script th:replace="fragments.html :: form-validation"></script>
</body>
</html>

 

 

참고: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-JPA-%EC%9B%B9%EC%95%B1#

 

스프링과 JPA 기반 웹 애플리케이션 개발 - 인프런

이 강좌에서 여러분은 실제로 운영 중인 서비스를 스프링, JPA 그리고 타임리프를 비롯한 여러 자바 기반의 여러 오픈 소스 기술을 사용하여 웹 애플리케이션을 개발하는 과정을 학습할 수 있습니다. 이 강좌를 충분히 학습한다면 여러분 만의 웹 서비스를 만들거나 취직에 도움이 될만한 포트폴리오를 만들 수 있을 겁니다. 활용 웹 개발 프레임워크 및 라이브러리 Java Spring Spring Boot Spring Data JPA Thymeleaf 온라인 강의 스

www.inflearn.com