Web/Django-python

Django에서 ajax와 세션을 이용하여 로그인 기능 구현하기

1. 장고에서 ajax 동작시키기

template 내에서 ajax를 작성하여 views.py에 정의된 view로 데이터를 보내고 그 결과값을 반환받는 동작을 만들어주자.

값을 전송할 시에는 .serialize() 함수를 이용해 데이터를 직렬화 해 주어야 POST 형태로 잘 넘어간다.

login.html

   $('#loginButton').on('click',function(event){

       var formData = $('#loginForm').serialize();
       $.ajax({
           cache : false,
           url : "{% url 'login:loginCheck' %}" ,
           type : 'POST',
           data : formData,
           success : function(data){
               var uid = data['uid'];
               var upass = data['upass'];
               console.log("id: "+uid+"pass : "+upass);
           },
           error : function(xhr,status,)
           {
               alert("실패");
           },
       });
   });

view.py 에서는 연결된 view에서 메소드에 따라 전달받은 데이터를 처리하여 response , 혹은 템플릿을 지정하여
render 해줘야 한다.

뷰 내에서 세션은 request.session[세션이름] 형태로 변수처럼 사용할 수 있다.

views.py

   def loginCheck(request):
       template_name = 'login.html'
       request.session['loginOk'] = False
       try:
           inputId = request.POST.get("id","")
           inputPassword = request.POST.get("password","")
       except (KeyError,inputId == "",inputPassword == "") :
           context = {
               "uid" : "empty",
               "upass" : "empty",
           }
           return render(request,template_name,context)
       else : 
           if( inputId == "hello" and inputPassword == "world") :
               request.session['loginOk'] = True
           else :
               request.session['loginOk'] = False
           context = {
               "uid" : inputId,
               "upass" : inputPassword
           }
           return HttpResponse(json.dumps(context),content_type="application/json")

이렇게 하면 loginbutton 클릭시에 login.html에서 loginForm 폼에 입력한 데이터가 loginCheck view로 전송되고, 해당 view에서는 입력받은 데이터중 id와 password가 특정 문자열과 일치하는지를 비교한 다음, session 값을 생성 혹은 조작하여 사용하게 만들 수 있다.

웹 페이지 상에서는 전송한 데이터에 해당하는 리턴값을 받은 다음, 성공적으로 리턴 받은 경우에는 로그창에 리턴값에 포함되어있는 입력 아이디와 비밀번호가 출력된다.


2. 세션의 사용

파이썬 코드에서는
request.session['세션이름']

의 형식으로 값을 사용한다.

템플릿에서는
{{ requset.session.이름 }} 로 값 내용을 가져오고
{{ if request.sssion.이름 }}식으로 사용한다.

장고 템플릿에서 {{%%}} 와 같은 문법은 랜더링 할때 완성되므로, 브라우저에서 이미 랜더가 완료된 페이지는 새로 페이지를 로드하지 않는 이상 변화가 없다.

따라서, 세션을 이용해 동적 페이지를 만들고 싶으면 ajax 와 view를 이용해 함수를 동작시켜서 view에서 세션값을 직접 체크해야 한 다음, 그 결과를 리턴하는 식으로 동작시켜야 한다.

login.html

   $('#loginCheck').on('click',function(event){
       window.open("{% url 'login:base' %}")

       var formData = $('#loginForm').serialize();
       $.ajax({
           cache : false,
           url : "{% url 'login:loginOk' %}",
           type : 'POST',
           data : formData,
           success : function(data){
               if (data['ok'] == "True")
                   console.log("로그인 성공");
               else
                   console.log("로그인 실패");
           },
           error : function(xhr,status,){
               alert("실패")
           },
       });
   });

login.html에서 logincheck 버튼을 클릭하면 ajax가 동작하여 loginOk view를 호출하고, 응답값에 따라 콘솔창 성공이나 실패 여부를 출력한다.

그와 동시에 로그인 여부를 체크하는 페이지 base.html 를 새 창에서 여는 동작도 하고있다.

base.html

   <html>
   login check page <br>
   {{ request.session.loginOk }}
   {% if request.session.loginOk == True %}
       로그인 성공
   {% else %}
       로그인 실패 
   {% endif %}
   </html>    

위 페이지는 새로 로드를 해야만 변화가 생기는 페이지로, 장고 템플릿 문법을 사용하여 현재 세션의 로그인 여부를 체크하는 페이지다.

이전 loginButton에서 ajax를 통해 이 페이지의 세션값을 변경하였고, 로그인에 성공했다면 이 페이지를 새로 로드할 때 로그인 성공이 뜰 것이다. 페이지를 새로 로드하지 않으면 내용은 변화하지 않는다.

views.py

   @csrf_exempt
   def loginOk(request):
       template_name = 'login.html'
       if request.session['loginOk'] == True :
           context = {
               "ok" : "True"
           }
       else :  
           context = {
               "ok" : "False"
           }
       return HttpResponse(json.dumps(context),content_type="application/json")

loginOk view는 현재 세션이 로그인 되었는지 여부를 체크하여 그에 따른 결과값을 리턴한다.

이 리턴값에 따라서 login.html 페이지의 동작이 달라지는 것이다. 이 경우는 새로 로드하지 않아도 내용이 변화할 수 있다.

즉, 현재 페이지를 새로 로드하지 않고 세션값을 사용하고 싶다면 ajax를 이용해 view와 연결하여 view에서 동작 처리를 완료한 다음 html로 다시 보내는 형태로 사용해야 하고,

그 외의 페이지를 새로 로드해도 되는 경우는 장고 템플릿을 사용하면 된다.