반원 블로그

django - 로그인 처리 (세션 이용) 본문

2018~/Django 개인 공부 정리

django - 로그인 처리 (세션 이용)

반원_SemiCircle 2019. 9. 6. 19:24
# Create your views here.
def login(request):
    if request.method=="GET":
        return render(request,'login.html')
    elif request.method == "POST" :
        #전송받은 이메일 비밀번호 확인
        username = request.POST.get('username')
        password = request.POST.get('password')
    
        #유효성 처리
        res_data ={}
        if not (username and password):
            res_data['error']="모든 칸을 다 입력해주세요"
        else:
            # 기존(DB)에 있는 Fuser 모델과 같은 값인 걸 가져온다.
            fuser = Fuser.objects.get(username = username) #(필드명 = 값)

            # 비밀번호가 맞는지 확인한다. 위에 check_password를 참조
            if check_password(password, fuser.password):
                #응답 데이터 세션에 값 추가. 수신측 쿠키에 저장됨
                request.session['user']=fuser.id

                #리다이렉트
                return redirect('/')
            else:
                res_data['error'] = "비밀번호가 틀렸습니다."

        return render(request,'login.html',res_data) #응답 데이터 res_data 전달

이미 MTV중 M은 Fuser를 만들었으니, T V를 만들자.

1. Templates

기존 register.html 을 이용하여 login.html을 만들자. (이메일, 비밀번호 확인만 없애면 됨)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <!-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> -->
    <link rel="stylesheet" href="/static/bootstrap.min.css">

    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
    <div class="container">
        <div class="row mt-5">
            <div class="col-12 text-center">
                <h1>로그인</h1>
            </div>
        </div>
        <div class="row mt-5">
            <div class="col-12">
                {{error}}
            </div>
        </div>
        
        <div class="row mt-5">
            <div class="col-12">
                <form method="POST" action=".">
                    {% csrf_token %}
                    <div class="form-group">
                        <label for="username">사용자 이름 입력</label>
                        <input type="text" class="form-control" id="username" name="username"  placeholder="사용자이름">
                    </div>
                    <div class="form-group">
                        <label for="password">비밀번호 입력</label>
                        <input type="password" class="form-control" id="password" name="password" placeholder="비밀번호">
                    </div>
                    <button type="submit" class="btn btn-primary">Submit</button>
                </form>
            </div>
        </div>

    </div>
</body>
</html>

 

2.VIEW

views.py에서 login 기능에 대한 함수 정의. 일단 페이지 연결만 해놓는다.

# Create your views here.
def login(request):
    return render(request,'login.html')

 

3. url 연결

앱 폴더의 urls.py에 추가

from django.urls import path
from . import views

urlpatterns = [
    path('register/', views.register),
    path('login/', views.login)
]

테스트 - 로그인 시도해서 에러만 안나면 성공(아직 뷰 처리 아무것도 안했기 때문)

 

4. V(iew) 코드 추가

실질적인 로그인 기능을 구현하기위해 def login 함수 코드를 수정한다.

테스트시, 비밀번호 틀렸을 때와 전부 공백일 때 처리 다 된다. 하지만 지금 코드에서 id를 다르게 입력하면 에러페이지로 이동한다. 일단 무시하고 세션 이용한 로그인 처리부터 먼저 구현하자.

(주의 : make_password를 통해 만든 계정은 비밀번호가 부호화 전이므로 로그인되지않는다. 비밀번호 비교시 check_password를 쓰고 있으므로)

 

5. V에 redirect(리다이렉트) 추가

from django.shortcuts import render, redirect 를 추가한다.

세션을 이용할 땐 render대신 redirect쓰며, 이 함수는 기능을 처리하고 어디로 갈지 적어준다. return redirect('사이트명')

보통은 홈 페이지로 이동을 위해 return redirect('/')를 적는편

return redirect('/') 가 실행되기 전에 세션처리 코드를 넣어주면 된다.

def login(request):
    if request.method=="GET":
        return render(request,'login.html')
    elif request.method == "POST" :
        #전송받은 이메일 비밀번호 확인
        username = request.POST.get('username')
        password = request.POST.get('password')
    
        #유효성 처리
        res_data ={}
        if not (username and password):
            res_data['error']="모든 칸을 다 입력해주세요"
        else:
            # 기존(DB)에 있는 Fuser 모델과 같은 값인 걸 가져온다.
            fuser = Fuser.objects.get(username = username) #(필드명 = 값)

            # 비밀번호가 맞는지 확인한다. 위에 check_password를 참조
            if check_password(password, fuser.password):
                #응답 데이터 세션에 fuser의 기본키(pk)값인 id 추가. 나중에 쿠키에 저장됨
                request.session['user']=fuser.id
                #리다이렉트
                return redirect('/')
            else:
                res_data['error'] = "비밀번호가 틀렸습니다."

        return render(request,'login.html',res_data) #응답 데이터 res_data 전달

 

6. 아직 '/'에 해당하는 루트 페이지가 없으니 생성

프로젝트 폴더의 urls.py에 '/' urlpattern 생성한다. urlpattern 적을 땐 맨 앞 / 는 제외하므로 다음처럼 작성된다.

from django.contrib import admin
from django.urls import path, include
from fuser.views import home

urlpatterns = [
    path('admin/', admin.site.urls),
    path('fuser/', include('fuser.urls')),
    path('',home)
]

현재 fuser.views 파일의 home 을 참조했지만 생성한 적이 없으니 생성하도록 하자.

# Create your views here.
def home(request):
    return HttpResponse("로그인 성공")

 

7. 세션값 이용해서 로그인 상태 표시하기

redirect를 통해서 루트 페이지('/')로 이동하라는 액션이 취해지고, 이를 urls.py가 감지하고 pattern에서 fuser.views.py의 home에 매핑되어있다.

이제 home 함수에 세션을 이용한 응답데이터를 만들어보자. 현재 데이터 requests는 돌고 도는 중이다.

login 당시에 requests.session['user']에 모델의 id값, 즉 기본키(primary key)를 넣어줬다. 이를 이용해 home함수 처리시 특정 유저임을 구분해낼 것이다.

# Create your views here.
def home(request):
    user_pk = request.session.get('user') #login함수에서 추가해준 requests.session['user'] = fuser.id

    if user_pk: #세션에 user_pk 정보가 존재하면
        fuser = Fuser.objects.get(pk=user_pk)
        return HttpResponse(fuser.username) #해당 유저의 Fuser모델의 username 전달

    return HttpResponse("로그인 성공") #세션에 유저 정보 없으면 그냥 home으로

한번 로그인하면 이제 바로 루트(127.0.0.1:8080)로 가도 로그인이 되어있다. 현재 브라우저에 해당하는 쿠키가 이미 생성되었고 sessionid(식별자)가 저장되있기 때문이다.

Comments