๋ฐฐ๊ฒฝ
๋ฏธ์
์งํ ์ค, ์์ฒญํ ์ฌ์ฉ์์ ๋ํ ์ธ์ฆ์ ์ํด token ๋ฐฉ์์ ์ฌ์ฉํ์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ jwt token ์ ํ์ฑํ๊ณ ์ ํจ์ฑ ๊ฒ์ฆ์ ํ๋ ค๊ณ ํ๋, Interceptor ์์๋ ํ๊ณ ArgumentResolver ์์๋ ํ๊ฒ ๋์์ต๋๋ค.
๋ฌธ์ ์
Interceptor - ArgumentResolver ๋ก ์ ๋ฌ๋๋ ์ธ์๋ Request(ServletRequest, WebRequest) ์ด๊ณ ํด๋น ๊ฐ์ฒด์์ ๊บผ๋ผ ์ ์๋ ์ ๋ณด๋ getHeader() ๋ก ๊บผ๋ผ ์ ์๋ ์คํธ๋ง์
๋๋ค. ์ด์ ๋ฐ๋ผ Interceptor ์์ ํ์ฑ๊ณผ ์ ํจ์ฑ ๊ฒ์ฆ์ ํ๋๋ฐ, ArgumentResolver ์์ ์์ฒญ๋ ํ๋ผ๋ฏธํฐ๋ก ๋ณํํ๊ธฐ ์ํด ํ์ฑ์ ๋ ํ๊ฒ ๋๋ ์ค๋ณต ๋ก์ง์ด ๋ฐ์ํ๋ ๊ฒ์ด์์ต๋๋ค. ๊ทธ๋ ๋ค๊ณ ArgumentResolver ์์๋ง ํ์ฑ, ์ ํจ์ฑ ๊ฒ์ฆ, ์์ฒญ ํ๋ผ๋ฏธํฐ ๋ณํ์ ๋ชจ๋ ๋งก๊ธฐ๊ธฐ์๋ ์ฑ
์์ง๋ ๋ก์ง์ด ๋ง์์ ธ, ์ด ์ฑ
์๋ค์ ๋ถ๋ฆฌํ ์ ์๋ ๋ฐฉ๋ฒ์ ์๊ฐํด ๋ณด์์ต๋๋ค.
Interceptor
Handlerย ์ฒ๋ฆฌย ์ ๊ณผย ํ์ย ์์ฒญ์ย ๋ํย ๊ณตํต์ ์ธ ๋ก์ง์ย ์คํํ ย ์ย ์๋ย AOPย ์ฑ๊ฒฉ์ย ์ง๋๋๋ค.
Argument Resolver
์ปจํธ๋กค๋ฌ์ย ๋ฉ์๋์ย ์ธ์๋กย ์ฌ์ฉ์๊ฐย ์์์ย ๊ฐ์ย ์ ๋ฌํ๋ย ๋ฐฉ๋ฒ์ย ์ ๊ณตํ๊ณ ์ย ํ ย ๋ย ์ฌ์ฉํฉ๋๋ค.
๋ฐ๋ผ์ ํ์ฑ๊ณผ ์ ํจ์ฑ ๊ฒ์ฆ์ Interceptor ์์ ํ๊ณ , ๊ฒ์ฆ์ ํต๊ณผํ๊ณ ๋ฐ์ payload ๋ ArgumentResolver ๋ก ์ ๋ฌํ ๋ค ํ๋ผ๋ฏธํฐ๋ก ๋ณํํ๋ ๋ก์ง์ ๊ตฌ์ํ์์ต๋๋ค.
Request ์ Attribute
์ฒ์์๋ย ๊ฐย ํ๋ผ๋ฏธํฐ๋กย ๋ฐ๋ย Requestย ์์ย attributeย ๋ฅผย ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํด ๋ณด์์ต๋๋ค.ย Interceptorย ์์๋ย ์ ํธ์ฑ ๊ฒ์ฆ์ ๋ง์นย payloadย ๋ฅผย attributeย ์ย setย ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ย Argumentย Resolverย ์์๋ย attributeย ์์ย getย ํ ๋ค ํ๋ผ๋ฏธํฐ๋ก ๋ณํํ๋ ๋ก์ง์
๋๋ค.ย ๊ฐ์ย Requestย Contextย ์์ย ์์ด์ย ์ ๋ฌ์ดย ๊ฐ๋ฅํ๊ณ ,ย ํ๋์ย ์์ฒญ์ดย ๋๋๋ฉดย ์ฌ๋ผ์ ธ ์ดํ์ ์์ฒญ์ ์ค๋ณต์ ๋ฌธ์ ๋ฅผ ์ผ์ผํค์ง ์์ต๋๋ค.
Scope
์์ ๊ฐ์ด Request ์ attribute ๋ฅผ ์ด์ฉํ๋ ๊ฒ๋ ๋ฐฉ๋ฒ ์ค ํ๋์ด์ง๋ง, ์ธ์ฆ๊ณผ ๊ด๋ จํด์ ์ง์ ๊ด๋ฆฌํ ์ ์๋ ๊ฐ์ฒด๊ฐ ์์ผ๋ฉด ์ข๊ฒ ๋ค๋ผ๋ ์๊ฐ์ด ๋ค์์ต๋๋ค. ์์ ๋ฐฉ๋ฒ์ servlet ์ attribute ๊ธฐ๋ฅ๊ณผ ๊ด๋ จํ์ฌ Map ๊ตฌ์กฐ๋ก ๋ฐ์ ์ฌ์ฉํ ์ ์๊ธฐ์ ์ดํ ํ์ฅ์ ์ธก๋ฉด์์ ๋จ์ ์ด ์์ ๊ฒ์ด๋ผ ํ๋จํ์ต๋๋ค. ์ด์ ๋ฐ๋ผ request ์ ๊ฐ์ ๋ผ์ดํ ์ฌ์ดํด์ ์ ์งํ ์ ์๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ๋ก ํ์์ต๋๋ค.
@Componen
@Scope(value = SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestTokenContext {
private String customerId;
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
}
Java
๋ณต์ฌ
1.ย ๋น์ผ๋ก ๋ฑ๋กํ๋ฉฐ ๋ผ์ดํ์ฌ์ดํด ์ฃผ๊ธฐ๋ฅผ ์คํ๋ง์ ๋งก๊ธฐ๋ฉด์, value = SCOPE_REQUEST ์ต์
์ผ๋ก ํด๋น ์ฃผ๊ธฐ๋ฅผ request ๋ก ์ ํ์์ต๋๋ค.
๋ ๋ฒ์งธ ์ต์
์ธ Proxy mode ๋ ์๋ฒ๊ฐ ๋ฐ ๋ ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ์์ฑํด์ฃผ๋ ์ต์
์ธ๋ฐ ์ดํ์ ์ค๋ช
ํ๊ฒ ์ต๋๋ค.
@Component
public class AuthenticationInterceptor implements HandlerInterceptor {
private final RequestTokenContext requestTokenContext;
public AuthenticationInterceptor(RequestTokenContext requestTokenContext) {
this.requestTokenContext = requestTokenContext;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
final String token = getTokenFromHeader();
validateToken(token);
final String payload = getPayload(token);
validatePayload(payload);
requestTokenContext.setCustomerId(payload);
return true;
}
}
Java
๋ณต์ฌ
RequestTokenContextย ๊ฐ์ฒด์ย payloadย ๋ฅผย set ํฉ๋๋ค. RequestTokenContext ์ย ํ๋์ย ์์ฒญ์ดย ๋๋ ย ๋ย ๊น์งย ๋น์ผ๋กย ๋ฑ๋ก๋์ดย ์ฌ์ฉ์ดย ๊ฐ๋ฅํฉ๋๋ค.
@Component
public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArgumentResolver {
private final RequestTokenContext requestTokenContext;
// ์์ฑ์ ์๋ต
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(AuthenticationPrincipal.class);
}
@Override
public Long resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
return Long.parseLong(requestTokenContext.getCustomerId());
}
}
Java
๋ณต์ฌ
Interceptor ์์ ๋ฑ๋กํย payloadย ๋ฅผย ๊ฐ์ ธ์ต๋๋ค. ArgumentResolver ์์๋ ํด๋น payload ๋ฅผ ๊ฒ์ฆํ์ง ์๊ณ ๋ฐ๋ก parameter ๋ก ๋๊ธธ ์ ์๋๋ก ๋ก์ง์ ๊ตฌ์ฑํ์์ต๋๋ค.
์์ ๋ฐฉ์์ผ๋ก ๋ ๊ฐ์ง ์ฅ์ ์ ๊ฐ์ง ์ ์์์ต๋๋ค.
1.
์ค๋ณต๋ ๋ก์ง์ ํผํ ์ ์๋ค.
โข
getHeader() ๋ก Interceptor ์ ArgumentResolver ์์ ํ์ฑ๊ณผ ์ ํจ์ฑ ๊ฒ์ฌ ๋ฑ์ ๋ก์ง์ด ์ค๋ณต๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
2.
์ดํ ๊ฐ์ ์์ฒญ ์ฃผ๊ธฐ์ Controller, Service ๋ฑ์์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
โข
๋น์ผ๋ก ๋ฑ๋กํ์๊ธฐ๋๋ฌธ์ ๋ผ์ดํ์ฌ์ดํด์ ์ด์์๋ ๋์ ์ด๋ค ๊ณ์ธต์์๋ , ์ฃผ์
์ ๋ฐ๊ธฐ๋ง ํ๋ฉด ํด๋น ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.