본문 바로가기
카테고리 없음

YAUAA -UserAgent활용하기(접속유저 정보 가져오기)

by 진믈리 2024. 11. 7.
프로젝트를 진행하던 도중 유저의 로그인 기록을 자세히 남기고싶었다. 접속한 디바이스, 그리고 OS가 무엇인지도 같이 저장하여, 어떤 종류의 디비이스를 사용하는 유저들이 많이 젒속하는지 파악하기 위해  User-Agent 문자열을 분석해 주는 라이브러리인 YAUAA를 사용해 보기로 했다.

 

YAUAA -> 공식문서 링크

 

라이브러리 설치

YAUAA를 사용하기 위해서는 라이브러리를 추가해 줘야 한다. 나는 yml을 사용하고 있기에 메이븐 리포지토리를 활용하여

implementation("nl.basjes.parse.useragent:yauaa:7.28.1")

의존성을 추가해 주었다.

 

 

config 생성

공식문서를 살펴보면 UserAgentAnalyzer 인스턴스를 생성해서 사용해야 하는데, 초기화 비용이 많이 든다고 한다. 그래서 나는 config 파일을 생성하여 스프링 빈으로 등록해 주기로 했다.

 

@Configuration
public class UserAgentConfig {

    @Bean
    public UserAgentAnalyzer userAgentAnalyzer() {
        return UserAgentAnalyzer
                .newBuilder()
                .hideMatcherLoadStats()
                .withCache(10000)
                .withField("DeviceClass")
                .withField("OperatingSystemName")
                .withField("AgentName")
                .build();

    }
}

 

.hideMatcherLoadStats() 는 YAUAA가 초기화 될때 내부 로드 상태 정보를 로그에 남기지 않게 하는것이다. 

.withCache(10000) 는 User-Agent 분석 결과를 캐시에 저장 하도록 설정하는 것인데 어차피 로그인 로직에서만 체크하고 따로 동일한 User-Agent에 대해 다시 분석할 일이 없을것 같아 메모리를 할당 하지 않기로 했다.

 

withField

withField를 활용하여 원하는 필드를 설정할 수 있다. 

  • ("DeviceClass") : 디바이스 (예 - 태블릿, 모바일, PC)
  • ("OperatingSystemName") : OS (예 - window, iOS, Android)
  • ("AgentName") : 브라우저 ( 예 - Chrom, safari

 

아래의 field name을 파스칼케이스로 활용하여 다양한 필드를 가져올 수 있다.

 

 

Service 구현

처음에는 Util 이름으로 클래스를 생성하였다가 스프링 빈을 등록해 주어야 하기에 Util이란 이름보다는 Service이름으로 생성하였다.

@Service
@RequiredArgsConstructor
public class UserAgentService {

    private final UserAgentAnalyzer userAgentAnalyzer;

    public String getDeviceClass(String userAgentString) {
        UserAgent userAgent = userAgentAnalyzer.parse(userAgentString);
        return userAgent.getValue("DeviceClass");
    }

    public String getOperatingSystem(String userAgentString) {
        UserAgent userAgent = userAgentAnalyzer.parse(userAgentString);
        return userAgent.getValue("OperatingSystemName");
    }

    public String getBrowser(String userAgentString) {
        UserAgent userAgent = userAgentAnalyzer.parse(userAgentString);
        return userAgent.getValue("AgentName");
    }

    public String isDevice(HttpServletRequest request){
        String userAgentString = request.getHeader("User-Agent");

        if (userAgentString == null || userAgentString.isEmpty()) {
            return "알 수 없는 기기";
        }

        String deviceClass = getDeviceClass(userAgentString);

        return deviceClass != null ? deviceClass : "알 수 없는 기기";
    }

    public String isOs(HttpServletRequest request){
        String userAgentString = request.getHeader("User-Agent");

        if (userAgentString == null || userAgentString.isEmpty()) {
            return "알 수 없는 운영체제";
        }

        String osName = getOperatingSystem(userAgentString);

        return osName != null ? osName : "알 수 없는 운영체제";
    }

    public String isBrowser(HttpServletRequest request){
        String userAgentString = request.getHeader("User-Agent");

        if (userAgentString == null || userAgentString.isEmpty()) {
            return "알 수 없는 브라우저";
        }

        String browserName = getBrowser(userAgentString);

        return browserName != null ? browserName : "알 수 없는 브라우저";
    }
}

 

 

OS 버전 오류

OS의 버전도 같이 가져오고 싶어 시도해 보았으나 버전이 잘 나오지 않는 버그를 발견했다.

 

공식문서를 살펴보니 브라우저들의 정책으로 자세한 정보가 나오지 않을 수 있다고 한다.

 

 

 

DB 결과물