쿠키를 사용하여 로그인 처리하기
도메인 Member
@Data
public class Member {
private Long id;
@NotEmpty
private String loginId; //로그인 ID
@NotEmpty
private String name; //사용자 이름
@NotEmpty
private String password;
}저장소 Repository
@Slf4j
@Repository
public class MemberRepository {
private static Map<Long, Member> store = new HashMap<>(); //static 사용
private static long sequence = 0L; //static 사용
public Member save(Member member) {
member.setId(++sequence);
log.info("save: member={}", member);
store.put(member.getId(), member);
return member;
}
public Member findById(Long id) {
return store.get(id);
}
public Optional<Member> findByLoginId(String loginId) {
return findAll().stream()
.filter(m -> m.getLoginId().equals(loginId))
.findFirst();
}
public List<Member> findAll() {
return new ArrayList<>(store.values());
}
public void clearStore() {
store.clear();
}
}컨트롤러
HTML
로그인 기능
쿠키 서버에서 로그인에 성공하면 HTTP 응답에 쿠키를 담아서 브라우저애 전달한다. 그러면 브라우저는 앞으로 해당 쿠키를 지속해서 보내준다.
영속 쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지된다.
세션 쿠키 : 만료 날짜를 생략하면 브라우저 종료시 까지만 유지된다.
로그인 서비스
로그인 DTO
로그인 컨트롤러
로그인에 성공하면 쿠키 이름=memberId, 값=회원의 id를 담아서 HttpServletResponse에 담는다. 웹 브라우저는 종료 전까지 회원의 id를 계속 보내준다.
홈 컨트롤러
@CookieValue를 사용하여 편리하게 쿠키를 조회할 수 있다. 로그인하지 않은 사용자도 홈에 접근 가능하게 하기 위해 required=false를 사용한다.
로그아웃
세션 쿠키이므로 웹 브라우저 종료 시 자동으로 로그아웃 되기도 하고, 서버에서 해당 쿠키의 종료 날짜를 0으로 지정할 수도 있다.
컨트롤러
쿠키 보안 문제
쿠키의 값을 임의로 변경할 수 있다.
클라이언트가 쿠키를 강제로 변경하면 다른 사용자가 될 수 있다.
웹 브라우저에 개발자 모드에서 실제로 변경이 가능하다.
쿠키에 보관된 정보는 훔쳐갈 수 있다.
쿠키 정보는 웹 브라우저에도 보관되고, 네트워크 요청마다 서버로 전달된다.
쿠키에 중요한 개인정보가 담겨 있다면 해커에게 털릴 시 매우 위험하다.
대안으로 여러 방법이 있다.
쿠키에 중요한 값을 노출하지 않고 사용자 별로 예측 불가능한 임의의 토큰(랜덤 값)을 노출하고, 서버에서 토큰과 사용자 ID를 매핑해서 인식한다. 토큰은 서버에서 관리한다.
토큰은 해커가 임의의 값을 넣어도 찾을 수 없도록 예측 불가능 해야 한다.
해커가 토큰을 털어가도 일정 시간 지나면 사용할 수 없도록 서버에서 해당 토큰의 만료 시간을 짧게 유지한다.(30분, 1시간...)
또는 해킹이 의심되는 경우 서버에서 해당 토큰을 강제로 제거한다.
Last updated