[패스트캠퍼스python] 세션session, 로그인화면만들기

[패스트캠퍼스python] 세션session, 로그인화면만들기

파이썬 인강 자기계발 챌린지 33회차 미션

1. 세션 Session

웹사이트 로그인 기능을 만들기위해 꼭 필요하면서도 중요한 개념인 세션에 대해 알아보자.

구조 설명
클라이언트 웹브라우저
쿠키 서버별 저장소
서버 서버
데이터베이스 클라이언트별 저장소

웹브라우저안에 쿠키라는 저장공간이 있다. 이를 통해 데이터를 유지할수있다.
이제 화살표이 흐름을 알아보자.

  1. 처음 웹사이트(alghost.com)에 접속한 클라이언트는 아무런 쿠키를 가지고있지않다.
  2. 클라이언트는 쿠키없이 서버에 요청을 한다 ex)www.naver.com
  3. 서버는 요청을 가지고 쿠키 키를 만든 뒤 헤더위치에 넣어서 클라이언트에게 응답한다.
  4. 서버는 만든 쿠키키를 데이터베이스에 저장한다.
  5. 클라이언트는 서버로부터 응답을 받으면서 쿠키를 쿠기저장소에 저장을 한다.
    1. 쿠키를 저장할때 각 웹사이트별로 나눠서 저장한다.
  6. 클라이언트는 두번째 요청부터 모든 요청에 가지고있는 쿠키를 함께 보낸다.
  7. 서버는 쿠키정보를 보고 “아 아까 그 클라이언트구나!”를 알게되고 데이터베이스에서 기존 쿠키를 꺼내 빠르게 응답할수있다.
    1. 이를 통해 서버는 클라이언트를 구분해서 인지할 수 있다.

세션은 처음에 어렵게 느껴질 수 있지만 Django를 이용하면 세션을 알아서 해주기때문에 편하다.




2. 로그인화면만들기

회원가입페이지에 이어 로그인페이지를 만들어보자.

1. HTML파일로 화면그리기

먼저 html파일로 간단한 틀을 만들 수 있다.
로그인페이지는 사용자명과 비밀번호입력창과 로그인버튼만 있으면 되기때문에 회원가입페이지보다 간단하게 만들 수 있다.

  1. error
    비밀번호가 일치하지 않는 경우 에러문구를 알려주는 코드이다.
    div태그를 감싸서 에러문구가 나오길 원하는 곳에 위치시켜주면된다.

  2. csrf_token
    크로스도메인을 막기위해 암호화키이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<body>
<div class="container">
<div class="row">
<div class="col-12">
<h1>로그인</h1>
</div>
</div>
<div class="row">
<div class="col-12">
{{ error }}
</div>
</div>
<div class="row">
<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"
placeholder="사용자 이름"
name="username">
</div>
<div class="form-group">
<label for="password">비밀번호</label>
<input
type="password"
class="form-control"
id="password"
placeholder="비밀번호"
name="password">
</div>
<button type="submit" class="btn btn-primary">로그인</button>
</form>
</div>
</div>
</div>
</body>



2. view.py에 비밀번호일치여부체크 함수구현하기

회원가입 페이지를 만들었던것처럼 먼저 views.py에 함수를 선언한다.
한꺼번에 모든 기능을 구현하는 것이 아니라 기본 기능부터 차근차근 구현하면서 코드를 진화시켜나가는 것이 좋다.
먼저 만들어 볼 기능은 가장 간단한 기능으로 아이디와 비밀번호가 다 입력되었는지 체크하고 입력되어있으면 비밀번호느 일치하는 지에 대한 함수를 코드로 구현할 것이다.

  1. render에 html파일 연결하기
    method는 get방식을 이용한뒤 render에는 위에서 만들었던 login.html을 연결해준다.
  1. if조건문 : get방식
    모든 데이터가 다 있을 경우 get방식으로 바로 login.html파일로 render한다.

  2. if조건문 : post방식
    post방식일 경우에는 데이터가 없으므로 데이터를 입력하라고 해야한다.
    이때 비밀번호 일치여부도 함께 확인한다.

  3. 모든값이 입력되었는지 확인 -> 비밀번호일치하는 지를 체크하느 순서대로 코드를 짠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def login(request):
if request.method == "GET":
return render(request, 'login.html')
elif request.method == "POST":
username = request.POST.get('username', None)
password = request.POST.get('password', None)

res_data = {} #불일치할때 데이터를 res_data라는 변수에 담는다.
if not (username and password ):
res_data['error'] = '모든 값이 입력되지 않았습니다'
else: #회원가입시 객체로 만들어놓은 fcuser의 데이터와 일치하는 지 확인
fcuser = Fcuser.objects.get(username=username) #(필드명=지정한값)
if check_password(password, fcuser.password):
# 리다이렉트
# 세션
pass
else:
res_data['error'] = '비밀번호를 틀렸습니다'

return render(request, 'login.html', res_data)

일부러 번호를 틀리면 아래와 같이 비밀번호를 틀렸습니다라는 error메세지가 제대로 출력되는 것을 확인 할수 있다.



3. view.py에 리다이렉트 함수구현하기

위에서 비밀번호일치여부까지 확인했다.
로그인할때를 떠올려보자.
비밀번호가 일치하고 난 뒤 계속 로그인페이지에 머무느 것이 아니라 main 콘텐츠가 있는 페이지로 자동이동이된다. 이를 redirect라고 한다.

  1. import redirect 하기
    리다이렉트를 사용하기 위해서는 import를 먼저 해줘야한다.
    장고숏컷 밑에 위치하고있기에 거기서 impor해주면된다.
1
from django.shortcuts import render, redirect
  1. return redirect(‘url’)
    redirect뒤에는 주소값을 입력해주면 된다.
    만약 ('http://naver.com)을 입력하면 로그인을 하고나면 네이버페이지로 이동하는 것이다.
    보통은 홈으로 이동을 하기때문에 아래와 같이 사용한다.
    /는 홈으로 가는 코드이다.
1
2
3
4
5
6
if check_password(password, fcuser.password):
# 세션
#리다이렉트
return redirect('/') #홈으로이동
else:
res_data['error'] = '비밀번호를 틀렸습니다'
  1. session
    request객체안에 sesssion이라는 변수가 있다. 딕셔너리처럼 이용하면 된다.
    user라는 키에다가 fufuser.id라는 값을 저장해주기만 하면 끝이다!
1
2
3
4
5
6
7
if check_password(password, fcuser.password):
# 세션
request.session['user']=fcuser.id
#리다이렉트
return redirect('/') #홈으로이동
else:
res_data['error'] = '비밀번호를 틀렸습니다'



4. home 간단히 표현하기

root에 연결하기전에 home을 간단히 만들어 로그인뒤 잘 넘어가는지 확인해봐야한다.
fcuser 하위의 views.py에 아래 코드를 입력한다.

1
2
3
4
5
6
7
8
9
def home(request):
user_id = request.session.get('user')

if user_id: #로그인되었으면 로그인한 유저네임출력
fcuser = Fcuser.objects.get(pk=user_id) #pk는 기본키라는 의미
return HttpResponse(fcuser.username)

#로그인을 안했다면 그냥 홈 텍스트만 출력
return HttpResponse('home!')



5. root설정

이제 기능들을 연결해줄 root를 설정해야한다.
어디다 설정하면 될까?

  • 1번선택 : fc_community 하위의 urls.py
  • 2번선택 : fcuser 하위의 urls.py

정답은 바로 1번이다!
fuuser 하위의 views.py에서 함수를 만들었지만 root연결은 fcuser상위폴더인 fc_community에 해야한다.

fc_community 하위의 urls.py에 아직 만들지않았지만 곧 만들 home을 import 해준 뒤 path('/', home)를 추가한다.

1
2
3
4
5
6
7
from fcuser.views import home #추가

urlpatterns = [
path('admin/', admin.site.urls),
path('fcuser/', include('fcuser.urls'))
path('', home) #추가
]