@PostMapping("")
public ApiSuccessResult<SignInAccountResponse> signInAccount (...) {
...
ResponseCookie cookie = ResponseCookie.from(JwtProvider.ACCOUNT_TOKEN_NAME, refreshToken)
.httpOnly(true)
.path("/")
.secure(true)
.sameSite("None")
.maxAge(COOKIE_VALIDATION_SECOND)
.build();
res.addHeader("Set-Cookie", cookie.toString());
return ApiUtil
.success(new SignInAccountResponse(account, accessToken, refreshToken));
}
String token = JWT.create()
.withIssuedAt(new Date(System.currentTimeMillis()))
.withExpiresAt(new Date(System.currentTimeMillis() + expireTime))
.withPayload(payload)
.withIssuer(ISSUER)
.sign(getSigningKey(SECRET_KEY));
기존의 방식에서는 서버에 영향력 있는 요청을 허가받을 수 있는 access token이 쿠키에 그대로 저장된다.
이 경우, CSRF나 XSS 공격 등에 노출되면 서버는 그대로 위조된 요청을 받을 위기에 처하게 된다.
공격에 대비하기 위한 여러 보안 기법들이 존재하지만, 서버는 기본적으로 사용자 정보를 보호하는 시스템을 구축 해야할 것이다. 인식된 취약점을 그대로 둘 수는 없다는 것이다.
쿠키에 Access Token을 저장하지 말자.
대신 Refresh Token을 쿠키에 넣어주고, 클라이언트 측에서 브라우저 렌더링 시마다 Refresh Token으로 Access Token을 재발급 받아 쿠키 등에 저장하지 않고 사용할 수 있도록 하자.
또한, Access Token을 발급할 때는 HTTP Response를 통해서 발급함으로써 CORS 정책에 의해 외부에서는 사용 불가하도록 하자.
이 경우, 공격을 당해도 Refresh Token만 노출되기 때문에 그것만 가지고는 서버에 위조 요청을 보낼 수가 없다.
기본적으로 스크립트 언어로 쿠키를 참조할 수 없도록 httpOnly 쿠키를 발행해서 Refresh Token도 노출되지 않도록 하자.
그리고 서비스 사용 중에 인증이 만료되지 않도록 Access Token 재발급 시 Refresh Token 유효기간의 1/2가 지났다면 Refresh Token도 쿠키를 통해 재발급 하자.
바꾼 인증 방식은 보안의 측면에서 개선되었지만, 렌더링 시마다 새로운 Access Token을 발급한다는 overload가 있다. 사용자 수가 크게 확대되고, 각 사용자가 렌더링을 할수록 부하가 커질 것이다.
따라서 Access Token 재발급 시마다 토큰을 새로 생성하는 기존 방식을 개선하기 위해 Redis를 이용하여 토큰을 캐싱해서 사용해보기로 했다.
- [HTTP 쿠키] https://ko.wikipedia.org/wiki/HTTP_%EC%BF%A0%ED%82%A4
http://www.tcpschool.com/php/php_cookieSession_cookie- [Session] http://www.tcpschool.com/php/php_cookieSession_session
- [JWT]
https://jwt.io/introduction
https://ko.wikipedia.org/wiki/JSON_%EC%9B%B9_%ED%86%A0%ED%81%B0#cite_note-rfc7519-1- [CSRF] https://ko.wikipedia.org/wiki/%EC%82%AC%EC%9D%B4%ED%8A%B8_%EA%B0%84_%EC%9A%94%EC%B2%AD_%EC%9C%84%EC%A1%B0
- [XSS] https://ko.wikipedia.org/wiki/%EC%82%AC%EC%9D%B4%ED%8A%B8_%EA%B0%84_%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8C%85
- [Redis]
https://aws.amazon.com/ko/elasticache/what-is-redis/
https://ko.wikipedia.org/wiki/%EB%A0%88%EB%94%94%EC%8A%A4- [이웃사이 사용자 인증 방식]
https://ppaksang.tistory.com/13
https://ppaksang.tistory.com/16