[Django] Request Header 활용 3 : 클라이언트 접속 환경 탐색

David Im·2022년 8월 11일
0

본 글은 야간모드에 최적화 되어있습니다. 우측 상단에서 해 혹은 달모양을 클릭시어 velog 설정을 야간모드로 해주시면 더욱 편안하게 읽으실 수 있습니다.

Request Header를 활용한 클라이언트 접속 환경 탐색

마지막으로 활용해볼 것은 클라이언트 접속 환경에 대한 내용이다.

리퀘스트 헤더를 통해서 브라우저의 언어도, IP도 알 수 있었으나 마지막으로 글로벌서비스에서 가장필요한 정보중에 하나라고 생각되는 사용하는 유저의 기기 정보이다.

글로벌 서비스이다 보니 워낙 사용자의 기기폭도 다양하고 설정들도 다양해서, 항상 오류접수나 문의시에 일일히 사용자의 환경을 확인하고 처리해야하는 불편함이 있었다.

하지만 이 정보를 수집하고나서는 조금이나마 그런 점이 해소 되었다.

Request Header에서 기기 정보를 가지고 있는곳

앞에서 설명한 내용들과 비슷하게 기기정보는 HTTP_USER_AGENT 라는 곳에 담겨있다.

이 HTTP_USER_AGENT 라는 곳에서 사용자의 접속 디바이스, OS버전, 브라우저 버전등을 전부 확인할 수 있는데 기본적으로 그냥 아래와 같이 사용하게 되면 정보를 알 수는 있지만 가공해서 사용하기 조금 어려운 형태로 보여진다.

user_agent = request.META['HTTP_USER_AGENT']

> user agent :: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36

django-user-agent를 통한 header 내의 클라이언트 접속 정보 가공

위에서 본 것처럼 보여지긴 하지만, 우리가 실제로 사용해서 쓰기에는 조금 무리가 있다.

물론 저 정보를 통째로 text 형식으로 저장해도 되겠지만, 각각의 기기 정보나 브라우저 정보같이 따로따로 나눠서 관리하고 싶었기 때문에 좀 더 쉽게 미들웨어와 pip 패키지를 통한 방법을 사용했다.

바로 django-user-agent 라는 패키지이다.

1. django-user-agent 패키지 설치

설치는 아래와 같이 pip install을 활용해서 진행한다.

pip install pyyaml ua-parser user-agents
pip install django-user-agents

위에 설치하는 ua-parser와 user-agent는 헤더에 들어있는 정보들을 파싱해주는 패키지이고, django-user-agents는 저것들을 우리가 쉽게 사용해서 쓸 수 있도록 가공해서 정보만 리턴해주는 패키지이다.

2. settings.py 미들웨어 설정

패키지를 설치했으면 settings.py에 미들웨어 설정과 install app 설정을 진행해준다.

# settings.py 내에 middleware 부분에 패키지 미들웨어 추가
MIDDLEWARE_CLASSES = (
    # other middlewares...
    'django_user_agents.middleware.UserAgentMiddleware',
)

# settings.py 내에 installed_apps 부분에 해당 패키지앱 추가
INSTALLED_APPS = (
    # Other apps...
    'django_user_agents',
)

# 캐시 사용하려는 경우 'default'로 설정, 그외에는 None으로 설정
USER_AGENTS_CACHE = 'None'

여기서 캐시를 활용하는 방법을 사용해줄 수 도 있는데 나는 따로 사용하지 않았다.

캐시활용은 선택사항인데 만약 활용해서 분석 속도를 높이고자 한다면 아래의 정보를 추가적으로 설정해주면 되고, 캐시를 이용하지 않을거라면 위와 같이 캐시 사용을 None으로 처리해주면 된다.

추가적으로 cache에 redis 같은 것들이 default로 설정되어있을 경우 아래 설정을 하게 될 경우 충돌이 날 수 있으니, 주의해서 적용하도록 하자.

# 캐시 적용 여부는 선택사항이지만, 사용자 기기 분석 정보 속도를 높이려면 활용하는 것이 좋다고한다.
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
    }
}

3. 실사용 방법 예시

다양한 옵션들을 제공하고 있는데 아래와 같은 내용들이 기본적으로 제공된다.

사용을 해보면 알겠지만, 굉장히 깔끔하게 분석해서 정보를 추려내준다.

기본적으로는 request.user_agent.~~~ 형식으로 사용한다.

  • request.user_agent.is~ : 기기 환경 판단
request.user_agent.is_mobile # 모바일기기 판단
request.user_agent.is_tablet # 태블릿기기 판단
request.user_agent.is_touch_capable # 터치가 가능한 기기인지 판단
request.user_agent.is_pc # 데스크톱, 랩탑등의 PC환경인지 판단
request.user_agent.is_bot # 봇인지 판단

위에 처럼 모바일,태블릿,PC,봇 여부에 대해서 판단해주는 옵션을 하며 리턴값은 boolean으로 제공한다.
ex) 맥북인 경우 위에서부터 각각 False, False, False, True, False가 리턴된다.

  • request.user_agent.browser : 클라이언트 브라우저 속성
request.user_agent.browser  # returns Browser(family=u'Mobile Safari', version=(5, 1), version_string='5.1')
request.user_agent.browser.family  # returns 'Mobile Safari'
request.user_agent.browser.version  # returns (5, 1)
request.user_agent.browser.version_string   # returns '5.1'

.browser를 타고 가보면 브라우저 속성에 대해서 확인할 수 있다.
기본적으로는 우리가 아까 HTTP_USER_AGENT에서 보았던 정보에서 브라우저 정보만 리턴시켜주고, 더 하위 속성으로 내려가서 요청하면 브라우저가 어떤 브라우저인지, 버전은 어떤지에 대해서도 알려준다.

추가적으로 모바일에서 사용하는 브라우저와 PC에서 사용하는 브라우저의 구분도 된다.
예를 들어 아이폰에서 크롬을 접속하면 Moblie Chrom으로 표기되고, 맥북에서 접속하면 Chrome으로 표기된다.


  • request.user_agent.os : 클라이언트 사용 OS 환경 속성
request.user_agent.os  # returns OperatingSystem(family=u'Mac OS', version=(10, 15, 7), version_string='10.5.7')
request.user_agent.os.family  # returns 'Mac OS'
request.user_agent.os.version  # returns (10, 15, 7)
request.user_agent.os.version_string  # returns '10.15.7'

해당 속성에서는 사용자가 어떤 기기 환경에서 접속하고 있는지 확인 할 수 있다.

맥북의 경우 M1은 아직 Intel Mac으로 인식하고, 표기 자체는 Mac OS로 표기되며, 버전은 해당 버전에 맞게 표기된다.

윈도우의 경우에는 역시 윈도우 11은 아직 업데이트가 안된듯 하고, 윈도우 10까지는 적용이되어있는것을 확인했다.

  • request.user_agent.device : 클라이언트 사용 기기 속성
request.user_agent.device  # returns Device(family='Mac')
request.user_agent.device.family  # returns 'Mac'

해당 속성에서는 사용자가 어떤 기기를 사용하고 있는지 확인 가능하다.

맥북에서는 Mac으로 표기되고, 아이폰에서는 iPhone, 아이패드에서는 iPad로 표기된다.
윈도우에서는 전부다 device는 Others로 표기되었다.

request header와 해당 패키지 사용시 주의 할 점!

안드로이드 계열쪽에서는 request header와 해당 패키지를 사용하는 결과 모두 브라우저를 가리는듯 하다.

갤럭시탭으로 시도해봤는데 갤탭S7의 경우에는 브라우저 사용에 따라 결과가 조금 상이하게 나왔는데 이점은 유의해야할 듯하다.

마이너한 브라우저들은 지원으로 안되어있는건가 싶어서 request.META.get('HTTP_USER_AGENT') 로도 확인해봤는데 각각의 브라우저에서 시도한 것과 똑같이 상이한 결과가 나타났다.

반면 이번년에 출시한 아이패드 미니6로 테스트했을때는 사파리, 크롬 모두 정상적으로 iPad로 잘인식해주었다. 아무래도 같은 iOS계열의 pad OS이기도 하고 버전만 더 높아진 버전이라 그런듯 싶다.

# 갤럭시탭S7에서 삼성브라우저로 시도한 결과 PC로 인식함 -> OS를 리눅스로 인식해서 그런듯
is desktop:: True
is tablet:: False
is mobile:: False
is device:: Other
is os:: Linux
is os version::

# 갤럭시탭S7에서 크롬브라우저로 시도한 결과 태블릿으로 인식함
is tablet:: True
is mobile:: False
is device:: SM-T870
is os:: Android
is os version:: 12

# 아이패드 미니6으로 시도한 결과 모바일,태블릿 둘다 True로 인식함
is tablet:: True
is mobile:: True
is device:: iPad
is os:: iOS
is os version:: 15.6

그래서 나는 다른부분은 동일하게 사용했지만 이 태블릿정보를 구분해주는 부분만 경우를 조금 구분지어서 사용했다.

갤럭시같은 안드로이드 OS는 태블릿은 True이지만, mobile은 False라서 그대로 두고,
iOS에 대해서 처리하는 내용을 is_mobile 아래에서 한번더 구분하여 is_tablet까지 True라면 태블릿으로 저장되도록 했다.

아래는 내가 실제로 쓰기위해 작성한 코드 전문이다. 필요하신분은 참고하시면 될 것 같다.

  • 예시코드
try:
	# 데스크탑, 랩톱 등 PC 환경
	if request.user_agent.is_pc:
		user_access_info['environment'] = 'Desktop'
	
    # iPhone, Galaxy 등 모바일 환경
    elif request.user_agent.is_mobile:
		user_access_info['environment'] = 'Mobile'

        # iPad의 경우 둘다 True로 리턴되기 때문에 안에서 tablet 정보도 true라면 아이패드로 처리하여 tablet으로 저장
		if request.user_agent.is_tablet:
        	user_access_info['environment'] = 'Tablet'

	# 안드로이드의 태블릿의 경우 mobile은 False로 리턴 -> 태블릿으로 저장
    elif request.user_agent.is_tablet and not request.user_agent.is_mobile:
    	user_access_info['environment'] = 'Tablet'

	# 나머지는 임의적으로 Others 로 저장하도록 처리
	else:
    	user_access_info['environment'] = 'Others'

	# 브라우저정보 및 os, device 정보 저장
   	user_access_info['browser'] = request.user_agent.browser.family
    user_access_info['browser_version'] = request.user_agent.browser.version_string
	user_access_info['system_os'] = request.user_agent.os.family
    user_access_info['os_version'] = request.user_agent.os.version_string
    user_access_info['device'] = request.user_agent.device.family
    
    return user_access_info
    
except:
	# 함수 시작 부분에 user_access_info의 key값별로 기본값을 지정해주었기때문에 로거만 남기고 기본값으로 리턴되도록 처리
    logger.debug(f'user_access_info ERROR :: {traceback.format_exc()})
    pass
    reutrn user_access_info

정리

request header 내에서 유저 기기정보를 확인하는 방법도 있고, 이처럼 django에서 지원하는 pip 패키지를 활용해서 좀 더 편하게 정보를 가공해 사용할 수 있는 방법도 있다.

기기정보들에 대해서는 안드로이드 쪽에서는 몇가지 주의사항이겠지만 대부분은 정확하게 버전까지 맞아떨어져서 저장된 데이터를 보고서 판단하기에는 나쁘지 않은듯하다.

일반적으로 맥/윈도우/리눅스 혹은 iOS/안드로이드 혹은 사파리/크롬/다른브라우저 형식으로 판단하니깐 큰 범주에서 유저 기기에 대한 정보를 구분하는데 충분할 듯 싶다.

개인적으로 사이드프로젝트를 시작하려고하는데 거기서도 나중에 적용할 수 있으면 적용 해봐야겠다


참고자료

profile
코더보다 개발자로, 결과와 과정의 시너지를 만들어 가고 싶은 주니어 개발자

0개의 댓글