스프링 부트 - 자동 로그인 (RememberMe)
- 로그인을 하면 자동으로 JSESSEIONID가 생성된다.- JSESSEIONID는 웹 브라우저와 서버와의 연결고리이다.
 
- 기본 세션의 timeout 값은 30분이다.(톰캣)
세션이 만료되더라도 로그인을 유지하고 싶을 때 사용하는 방법
- Remember-me는 쿠키를 사용한다. 인증을 하면, 쿠키에 암호화한 인증 정보를 담아둔다. 이 값은 세션이 만료되었거나 세션이 없는 경우 같이 보내온 Remembe-me 쿠키가 있으면 그 쿠키에 있는 인증정보를 인증을 시도한다. 
- 인증을 성공하면, 새로운 세션 id와 쿠키가 발급된다. 
- 해시 기반의 쿠키 - 사용자의 username, password를 암호화(해싱)하여 쿠키에 담아둔다. - 그러면 요청에 해당하는 세션을 찾지 못할 때, 함께 보내온 RememberMe 쿠키가 있다면 그 쿠기에 들어있는 인증 정보로 인증을 시도한다.
- 그 username, password로 인증이 되면 새로운 세션ID와 쿠키가 발급이 되는 것이다.
- 이 쿠키가 탈취당한다면 그 계정은 탈취당한 것과 같다.
- http.rememberMe().key("asfasasdf")와 같이 사용 가능
 
- 조금 더 안전한 방법 - 쿠키 안에 랜덤한 문자열(토큰)을 만들어 같이 저장하고 매번 인증할 때마다 바꾼다.
- username, 토큰
- 쿠키가 탈취당한 경우 새롭게 인증을 하면 탈취당한 쿠키는 더 이상 사용이 불가능 하다.
- 하지만 해커가 탈취한 쿠키로 먼저 인증을 하면 해커의 쿠키만 유효하게 된다.
- 이 방법은 스프링 부트에서 지원하지 않음.
 
- 조금 더 개선한 방법 - username, 토큰(랜덤, 매번 바뀜), 시리즈(랜덤, 고정)
- 쿠키가 탈취 당한 경우, 희생자는 유효하지 않은 토큰 과 유효한 시리즈와 Username 으로 접속하게 된다.
- 이 경우, 쿠키가 탈취당해 누군가에 의해 사용되었다는 뜻이 되므로
- 모든 토큰을 삭제하여 해커가 더 이상 탈취한 쿠키를 사용하지 못하도록 방지할 수 있다.
- 이렇게 되면 form기반의 로그인 창으로만 로그인을 하여 인증이 가능하게 된다.
 
- SecurityConfig.java에서 다음과 같이 사용 가능- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 // 스프링 시큐리티 설정을 직접하겠다는 뜻
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
 private final AccountService accountService;
 private final DataSource dataSource;
 
 protected void configure(HttpSecurity http) throws Exception {
 http.rememberMe()
 .userDetailsService(accountService)
 .tokenRepository(tokenRepository());
 }
 
 public PersistentTokenRepository tokenRepository() {
 // JDBC 기반의 tokenRepository 구현체
 JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
 jdbcTokenRepository.setDataSource(dataSource); // dataSource 주입
 return jdbcTokenRepository;
 }
 }
- JdbcTokenRepositoryImpl가 사용하는 테이블이 있어야 한다.
- 해당 스키마가 생성될 수 있도록 매핑이 되는 엔티티가 필요하다. 
- PersistentLogins.java: 쿠키 값을 사용하기 위한 엔티티- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19- (name = "persistent_logins") 
 
 public class PersistentLogins {
 
 (length = 64)
 private String series;
 (nullable = false, length = 64)
 private String username;
 (nullable = false, length = 64)
 private String token;
 (name = "last_used", nullable = false, length = 64)
 private LocalDateTime lastUsed;
 }
- login.html에 로그인 유지 체크박스를 추가해준다.- 1 
 2
 3
 4- <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>
참조
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-JPA-%EC%9B%B9%EC%95%B1/dashboard
