본문 바로가기

Web Programming/Django

로그인 & 회원가입

1. 틀 완성


장고에서는 패키지를 통해 로그인과 회원가입 기능을 구현할 수 있다

먼저 계정 app을 추가하고 포함시켜주어야 한다


1
$ python manage.py startapp accounts
cs


그리고, 기존의 프로젝트 settings.py에서 해당 app을 연결시켜준다

다음 accounts 앱의 template를 추가해주고 html 파일을 작성해준다


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
# project/accounts/signup.html
 
{% extends 'base.html' %}
 
{% block content %}
 
<h1>Sign Up!</h1>
 
<form>
    Username:
    <br>
    <input name="username" type="text" value="">
    <br>
    Password:
    <br>
    <input name="password1" type="password" value="">
    <br>
    Confirm Password:
    <br>
    <input name="password2" type="password" value="">
    <br>
    <br>
    <input class="btn btn-primary" type="submit" value="Sign Up!">
</form>
 
{% endblock %}
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# project/accounts/login.html
 
{% extends 'base.html' %}
 
{% block content %}
 
<h1>Login</h1>
 
<form>
    Username:
    <br>
    <input name="username" type="text" value="">
    <br>
    Password:
    <br>
    <input name="password" type="password" value="">
    <br>
    <br>
    <input class="btn btn-primary" type="submit" value="Login">
</form>
 
{% endblock %}
cs

(extends를 통해 navbar를 가져와서 사용하였다)


그리고 해당 template를 view에 연결시켜준다
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib import auth
1
2
3
4
5
6
7
# project/accounts/views.py
 
def signup(request):
    return render(request, 'accounts/signup.html')
 
def login(request):
    return render(request, 'accounts/login.html')
cs


현재는 간략하게 화면만 띄워보는 것을 목표로 간략하게 render로 띄워본다

그리고 해당 App의 url을 작성해주고 프로젝트의 url에 연결해준다


1
2
3
4
5
6
7
8
9
# project/accounts/urls.py
 
from django.urls import path
from . import views
 
urlpatterns = [
    path('signup/', views.signup, name='signup'),
    path('login/', views.login, name='login'),
path('logout/',views.logout, name='logout'),
]
cs


1
2
3
4
5
# project/urls.py
urlpatterns = [
       ...
    path('accounts/',include('accounts.urls')),
]
cs


이렇게하고 해당 url을 통해 sign up과 login 페이지를 띄우면 다음과 같이 나타난다!



2. 기능 구현


이렇게 틀을 완성시킨 후 실제 기능을 담기 위한 보완작업을 한다

먼저 template 파일을 수정한다


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
# project/accounts/templates/signup.html
{% extends 'base.html' %}
 
{% block content %}
 
<h1>Sign Up!</h1>
 
<form method="POST" action="{% url 'signup'%}">
 
{% csrf_token %}
Username:
<br>
<input name="username"  type="text" value="">
<br>
Password:
<br>
<input name="password1"  type="password" value="">
<br>
Confirm Password:
<br>
<input name="password2"  type="password" value="">
<br>
<br>
<input class="btn btn-primary" type="submit" value="Sign Up!">
</form>
 
{% endblock %}
cs

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
# project/accounts/templates/login.html
 
{% extends 'base.html' %}
 
{% block content %}
 
{% if error %}
{{ error }}
<br>
<br>
{% endif %}
 
<h1>Login</h1>
 
<form method="POST" action="{% url 'login'%}">
 
    {% csrf_token %}
    Username:
    <br>
    <input name="username" type="text" value="">
    <br>
    Password:
    <br>
    <input name="password" type="password" value="">
    <br>
    <br>
    <input class="btn btn-primary" type="submit" value="Login">
</form>
 
{% endblock %}
cs

여기서, csrf_token은 보안을 위한 토큰처리를 한 것이고

form의 통신 방식은 기존의 get에서는 모든 정보를 url로 넘기는 것은 위험하기에 post 방식을 통하여 통신을 하도록 한다

참고로, http의 메소드는 다음과 같이 활용이 된다

  • GET - 데이터 조회(READ)
  • POST - 데이터 생성(CREATE)
  • PUT - 데이터 수정(UPDATE)
  • DELETE - 데이터 삭제(DELETE)

그리고, view도 맞게 변경시켜준다


1
2
3
4
5
6
7
8
9
10
11
12
13
# project/accounts/views.py
 
def signup(request):
    # 포스트 방식으로 들어오면
    if request.method == 'POST':
        # 비밀번호 확인도 같다면
        if request.POST['password1'==request.POST['password2']:
            # 유저 만들기
            user = User.objects.create_user(username=request.POST['username'], password=request.POST['password1'])
            auth.login(request,user) #로그인
            return redirect('home'# 블로그페이지
    # 포스트 방식 아니면 페이지 띄우기
    return render(request, 'signup.html')
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# project/accounts/views.py
 
def login(request):
    # 포스트 방식으로 들어오면
    if request.method == 'POST':
        # 정보 가져와서 
        username = request.POST['username']
        password = request.POST['password']
        # 로그인
        user = auth.authenticate(request, username=username, password=password)
        # 성공
        if user is not None:
            auth.login(request, user)
            return redirect('home')
        # 실패
        else:
            return render(request, 'login.html', {'error''username or password is incorrect.'})
    else:
        return render(request, 'login.html')
cs


1
2
3
4
5
6
7
8
9
# project/accounts/views.py
 
def logout(request):
    # 포스트 방식으로 들어오면
    if request.method == 'POST':
        # 유저 로그아웃
        auth.logout(request)
        return redirect('home')
    return render(request, 'accounts/signup.html')
cs


그리고, 이제 Navbar에 로그인과 회원가입 링크를 걸어주도록 한다


1
2
3
4
5
6
7
8
9
10
11
12
# project/templates/base.html
 
{% if user.is_authenticated %}
    <class="nav-link" style="color:white;">{{ user.username}}님! 환영합니다 </a>
    <class="nav-link" href="javascript:{document.getElementById('logout').submit()}">Logout</a>
        <form id="logout" method="POST" action="{% url 'logout' %}">
            {% csrf_token %} <input type="hidden" />
        </form>
{% else %}
    <class="nav-link" href="{% url 'login' %}">로그인</a>
    <class="nav-link" href="{% url 'signup' %}">회원가입</a>
{% endif %}
cs