반응형
저번 글에 Redis를 사용해 조회수를 구현했었다.
하지만 저번 로직은 가장 큰 문제가 있다.
해당 API를 계속 누르면 카운트가 계속 올라간다, 이렇게 만들면 한 유저가 그냥 페이지를 계속 새로고침 하면 조회수가 계속 올라가게 된다.
그렇기에 이것을 막기 위해 유저마다 조회수 올라가는 것에 대기 시간을 주기로 했다.
처음에는 HttpServletRequest에서 유저들의 IP를 받아오고 해당 IP들을 redis에 저장을 한 뒤 해당 IP가 존재하면 카운트를 하지 않는 방법을 생각했었다.
하지만 추천하지 않는 방법이라고 한다.
우선 사용자의 IP가 변할 수 있다. IP는 유동적으로 변할텐데, 만약 바뀐다면 같은 유저라도 카운트가 될 수 있기 때문이다.
그리고 Redis에 용량에 부담이 가게 되며, 유저들의 IP를 가지고 있는 것 또한 보안에 문제가 될 수 있다고 한다.
그래서 생각한 방법이 처음 접속을 하면 해당 유저에게 쿠키를 넣어주고 만약 쿠키를 체크했을 때 쿠키가 있다면 조회수를 증가시키지 않는 방법이다.
public ResponseEntity<AllHitRes> hit(
@ApiIgnore @CookieValue(value = "hitCookie", defaultValue = "0") Integer hitCookie,
HttpServletResponse httpServletResponse){
return allService.getHit(hitCookie, httpServletResponse);
}
이렇게 Controller에서 쿠키를 가져온다.
private final RedisTemplate<String, String> redisTemplate;
@Transactional
public ResponseEntity<AllHitRes> getHit(Integer hitCookie, HttpServletResponse httpServletResponse){
if(hitCookie == 0) IncrementTodayAndSetCookie(httpServletResponse);
Long today = Long.parseLong(Objects.requireNonNull(redisTemplate.opsForValue().get("today")));
Long total = Long.parseLong(Objects.requireNonNull(redisTemplate.opsForValue().get("total")));
return new ResponseEntity<>(new AllHitRes(today, today + total), HttpStatus.OK);
}
private void IncrementTodayAndSetCookie(HttpServletResponse httpServletResponse){
redisTemplate.opsForValue().increment("today");
Cookie cookie = new Cookie("hitCookie", "1");
cookie.setMaxAge(900);
httpServletResponse.addCookie(cookie);
}
Service에서 체크를 하고 만약 hitCookie가 default 값인 0이라면 15분 유효의 쿠키를 넣어주고 today의 값을 1 증가시켜 준다.
이렇게 구현을 하니 쿠키를 직접 지우지 않는 이상 중복된 접속은 조회수가 증가를 하지 않게 되었다.
'블로그 개발 프로젝트' 카테고리의 다른 글
Redis를 사용한 조회수 구현 (0) | 2023.08.10 |
---|---|
Redis ERR value is not an integer or out of range (0) | 2023.08.09 |
Nginx에 페이지 연결하기 (0) | 2023.08.07 |
EC2에 Nginx 초기 설정 (0) | 2023.08.05 |
ExceptionHandler (0) | 2023.07.28 |