본문 바로가기
컴퓨터 프로그래밍/Spring

[Spring] AuthUser 예시 코드 분석

by 한33 2024. 9. 21.

@Auth

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Auth {
}

 

annotation 패키지에 Auth 어노테이션으로 파일 생성


AuthUser

@Getter
public class AuthUser {
    private final Long id;
    private final String userName;
    private final String email;
    private final UserRole userRole;

    public AuthUser(Long id, String userName, String email, UserRole userRole) {
        this.id = id;
        this.userName = userName;
        this.email = email;
        this.userRole = userRole;
    }
}

 

AuthUser 에 Filter 로 부터 담아올 필드를 지정해준다.

 


AuthUserArgumentResolver

package com.sparta.sweethoney.config;

import com.sparta.sweethoney.domain.common.annotation.Auth;
import com.sparta.sweethoney.domain.common.dto.AuthUser;
import com.sparta.sweethoney.domain.user.entity.UserRole;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

public class AuthUserArgumentResolver implements HandlerMethodArgumentResolver {
    // @Auth 어노테이션이 있는지 확인
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        boolean hasAuthAnnotation = parameter.getParameterAnnotation(Auth.class) != null;
        boolean isAuthUserType = parameter.getParameterType().equals(AuthUser.class);
        if(hasAuthAnnotation != isAuthUserType) {
            throw new IllegalArgumentException("@Auth Annotation 와 AuthUser Type 은 함께 사용되어야 합니다.");
        }
        return hasAuthAnnotation;
    }

    // AuthUser 객체를 생성하여 반환
    @Override
    public Object resolveArgument(
            @Nullable MethodParameter parameter,
            @Nullable ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest,
            @Nullable WebDataBinderFactory binderFactory
    ) {
        HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();

        // JwtFilter 에서 set 한 userId, email 값을 가져옴
        Long userId = (Long) request.getAttribute("userId");
        String userName = (String) request.getAttribute("userName");
        String email = (String) request.getAttribute("email");
        UserRole userRole = (UserRole) request.getAttribute("userRole");

        return new AuthUser(userId, userName, email, userRole);
    }
}
// @Auth 어노테이션이 있는지 확인
@Override
public boolean supportsParameter(MethodParameter parameter) {
    boolean hasAuthAnnotation = parameter.getParameterAnnotation(Auth.class) != null;
    boolean isAuthUserType = parameter.getParameterType().equals(AuthUser.class);
    if(hasAuthAnnotation != isAuthUserType) {
        throw new IllegalArgumentException("@Auth Annotation 와 AuthUser Type 은 함께 사용되어야 합니다.");
    }
    return hasAuthAnnotation;
}

 

parameter 를 확인해서 @Auth 어노테이션이 있고, AuthUser 클래스가 같이 사용되었는지 확인한다.

만약 함께 사용이 안되었다면 예외처리.

 

// JwtFilter 에서 set 한 userId, email 값을 가져옴
Long userId = (Long) request.getAttribute("userId");
String userName = (String) request.getAttribute("userName");
String email = (String) request.getAttribute("email");
UserRole userRole = (UserRole) request.getAttribute("userRole");

return new AuthUser(userId, userName, email, userRole);

 

Filter 로 부터 받은 데이터들을 각각의 필드에 넣어준다음, 위에 AuthUser 에서 지정한 필드값에 넣어서 전달한다.

이러면 컨트롤러에서 authUser.getId() 이런 식으로 원하는 값을 가져올 수 있다.


WebConfig

@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {

    // ArgumentResolver 등록
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new AuthUserArgumentResolver());
    }
}

 

config 패키지 안에 Webconfig 파일을 만든 다음 연결시켜준다.