수학과의 좌충우돌 프로그래밍

[Django]로그인 유지하기, 쿠키와 세션 본문

웹프로그래밍/Django

[Django]로그인 유지하기, 쿠키와 세션

ssung.k 2019. 5. 9. 22:02

저번 포스팅에서 HTTP 통신에 대해서 알아보았습니다. 그리고 이 정보는 상태 비 저장 프로토콜 입니다.우리가 로그인을 할 때 아이디와 비밀번호의 정보도 HTTP 통신 중 POST 방식으로 보내기 떄문에 이 정보는 저장이 되지 않습니다. 그렇기 때문에 로그인 유지하기 기능을 구현하기 위해서는 다른 방법을 사용해야 합니다. 그 방법으로 쿠키세션을 알아보도록 하겠습니다.

  • 쿠키(Cookie)

    • 쿠키란?

      • 클라이언트인 웹 브라우저 로컬에 저장하는 키와 값이 들어있는 작은 데이터 파일
    • 만료시점

      • 사용자 인증이 유효한 시간을 명시 가능, 브라우저가 종료되도 유효시간이 남아있으면 인증이 유지 됨
    • 쿠키 구성 요소

      • 이름 : 각각의 쿠키에 대한 식별자
      • 값 : 쿠키의 이름과 관련된 값
      • 유효시간 : 쿠키의 유지시간
      • 도메인 : 쿠키를 전송할 도메인
      • 경로 : 쿠키를 전송할 도메인
    • 용량제한

      • 한 도메인 당 20개, 모든 도메인에 대해 300개 제한, 하나의 쿠키는 4KB
      • 클라이언트도 모르게 접속되는 사이트에 의해서 설정 될 수 있기 때문에 쿠키로 인한 문제가 발생하는 것을 막고자 제한을 걸어놓았다.
      • 하나의 도메인에서 쿠키가 20개를 초과하면 가장 적게 사용된 쿠키부터 삭제
    • 쿠키 동작 방식

      • 클라이언트가 페이지 요청
      • 서버에서 쿠키 생성
      • HTTP 헤더에 쿠키를 포함시켜 응답
      • 브라우저가 종료되어도 쿠키 만료 기간이 있다면 클라언트에서 보관하고 있음
      • 같은 요청을 할 경우 HTTP 헤더에 쿠키를 함께 보냄
      • 서버에서 쿠키를 읽어 이전 상태 정보를 변경할 필요가 있을 때 쿠키를 업데이트 하여 변경된 쿠키를 HTTP 헤더에 포함시켜 응답
    • 예시

      • 방문 사이트에서 로그인 시, 아이디와 비밀번호를 저장하시겠습니까?

      • 쇼핑몰의 장바구니 (비 로그인시 장바구니에 담았던 품목을 로그인 시 그대로 유지하기 위해서 사용)

  • 세션

    • 세션이란?

      • 일정 시간 동안 같은 사용자, 브라우저로부터 들어오는 일련의 요구를 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술
      • 쿠키를 기반, 차이점은 사용자 정보를 브라우저에 저장하지 않고 서버에서 관리
    • 만료시점

      • 서버에서는 클라이언트를 구분하기 위해서 세션 ID 를 부여하여 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태 유지
    • 세션의 장점

      • 클라이언트의 정보를 서버에 저장하기 때문에 쿠키보다 보안에 우수
    • 세션의 단점

      • 쿠키보다 보안 면에서 우수하지만 사용자가 많아질경우 서버 메모리를 많이 차지하게 됨 -> 성능 저하의 요인
    • 세션의 동작 방식

      • 클라이언트가 서버에 접속시 세션 ID 를 발급
      • 클라이언트는 세션 ID 에 대해 쿠키를 사용하여 저장
      • 클라이언트가 서버에 다시 접속 시 이 쿠키를 이용해서 세션 ID 값을 서버에 전달
    • 로그인과 같이 보안 상 중요한 작업

쿠키와 세션에 대해서 알아보았습니다. 이제 쿠키를 통해 로그인 유지 기능을 구현해보도록 하겠습니다.

  • 쿠키 만들기

    set_cookie(name, value, max_age=None)
    

    쿠키를 만들기 위해서는 2개의 필수 인수와 1개의 선택적 인수가 필요합니다.

    • name : 쿠키의 이름 (필수)
    • value : 쿠키에 저장하려는 값(필수)
    • max_age: 쿠키의 경과 시간 (초), 지정하지 않으면 브라우저가 닫힐 때까지 쿠키가 존재(선택)
  • 쿠키 읽기

    request.COOKIE[name]
    

    쿠키는 딕셔너리와 같은 속성을 가지고 있습니다. 물론 딕셔너리는 아니고 object 입니다. 쿠키 데이터를 읽으면 수가 아닌 문자열로 반환합니다.

이 두 가지 메소드를 이용하여 로그인 유지 기능을 구현하였습니다.

def login(request):
    # 해당 쿠키에 값이 없을 경우 None을 return 한다.
    if request.COOKIES.get('username') is not None:
        username = request.COOKIES.get('username')
        password = request.COOKIES.get('password')
        user = auth.authenticate(request, username=username, password=password)
        if user is not None:
            auth.login(request, user)
            return redirect("account:home")  
        else:
            return render(request, "account/login.html")

    elif request.method == "POST":
        username = request.POST["username"]
        password = request.POST["password"]
        # 해당 user가 있으면 username, 없으면 None
        user = auth.authenticate(request, username=username, password=password)

        if user is not None:
            auth.login(request, user)
            if request.POST.get("keep_login") == "TRUE":
                response = render(request, 'account/home.html')
                response.set_cookie('username',username)
                response.set_cookie('password',password)
                return response
            return redirect("account:home")
        else:
            return render(request, 'account/login.html', {'error':'username or password is incorrect'})
    else:
        return render(request, 'account/login.html')
    return render(request, 'account/login.html') 

그리고 logout 시에는 저장한 쿠키를 없애주도록 하겠습니다.

def logout(request):
    response = render(request, 'account/home.html')
    response.delete_cookie('username')
    response.delete_cookie('password')
    auth.logout(request)
    return response

COOKIE가 저장되었는지 확인하기 위해서는 개발자도구Application 으로 들어갑니다. 그러면 아래 이미지와 같이 username 과 password가 저장된 것을 확인할 수 있습니다.

하지만 password가 그대로 저장되어 노출의 위험이 있으니 이에 대해서는 다음에 해결해보도록 하겠습니다.

Comments