TIL(24일차)

김규현·2022년 10월 6일
0

팀 프로젝트를 진행하면서 다른 팀원이 회원가입과 로그인 기능을 구현하였다.
회원가입과 로그인은 user 모델에 해당하며 모델은 아래와 같다.

📌models.py

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings

# Create your models here.
class UserModel(AbstractUser):
    class Meta:
        db_table = "user_table"

    username = models.CharField(max_length=20,null=False, primary_key=True)
    password = models.CharField(max_length=256,null=False)
    bio = models.CharField(max_length=256, default='')
    user = models.CharField(max_length=8, blank=False)
    phone = models.CharField(max_length=256,null=True,unique=True)

사용자로부터 받을 정보는 아이디, 비밀번호, 상태메시지, 이름, 연락처이고 모두 charField로 모델을 설계했으며 아이디와 비밀번호는 반드시 입력해야 하기에 null값을 False로 두고, 이름은 빈값을 허용하지 않기 위해 blank를 False로 두었다.
그리고 연락처는 중복 가입이 안될 수 있도록 unique를 True로 두면서 필수조건이 아니기에 null 값을 True로 설정해두었다.

✔️ 여기서 아쉬웠던 점은 username이 아이디 값이고, user가 사용자 이름인데 네이밍 컨벤션을 정하지 않아 무엇이 아이디이고 사용자 이름인지 헷갈리는 점이었고, username에 unique를 설정하지 않아 중복으로 가입이 되는 것이었다.

📌urls.py

from django.urls import path, include
from django.views.decorators.csrf import csrf_exempt
from . import views

app_name = "user"
urlpatterns = [
    path('signup/', views.signup, name='signup'), 
    path('login/', views.login, name='login'),   
]

회원가입과 로그인을 할 경로를 설정해두었고 회원가입시 views.py의 signup 함수가, 로그인시 login 함수가 실행된다.

📌views.py

#회원가입

@csrf_exempt
def signup(request):
    if request.method == 'GET':
        user = request.user.is_authenticated
        if user:
            return redirect('/main')
        else:
            return render(request, 'user/signup.html')
    
    elif request.method == "POST":
        username = request.POST.get('username','')
        userpw = request.POST.get('userpw','')
        userpw2 = request.POST.get('userpw2','')
        user = request.POST.get('user','')
        useremail = request.POST.get('useremail','')
        phone = request.POST.get('phone','')
        bio = request.POST.get('bio','')


        if userpw != userpw2:
            return render(request, 'user/signup.html',{'error':'패스워드를 확인해주세요!'})
        else:
            if username == '' or userpw == '':
                return render(request, 'user/signup.html',{'error':'사용자 이름과 비밀번호는 필수입니다!'})
            exist_user = get_user_model().objects.filter(username=username)
            if exist_user:
                return render(request, 'user/signup.html',{'error':'사용자가 이미 존재합니다!'})
            else:
                user_table = UserModel()
                user_table.username=username
                user_table.set_password(userpw2)
                user_table.user=user
                # user_table.user_img=userimg
                user_table.email=useremail
                user_table.phone=phone
                user_table.bio=bio
                user_table.save()
        
                return redirect('/login')

signup의 함수는 사용자의 요청이 GET인 경우 로그인 상태인지 판별하여 로그인 상태면 main으로 이동, 비로그인 상태면 회원가입 창을 띄워준다.

사용자의 요청이 POST인 경우는 사용자의 입력 정보를 전달받아 비밀번호 재확인을 하고 아이디와 비밀번호가 빈 값이 아닌지, 또 filter 함수를 통해 db에 사용자가 입력한 아이디가 있는지 중복 검사를 한 후 모든 조건에 걸리지 않는다면 정보를 저장하고 login 페이지로 이동해준다.

#로그인

def login(request):
    if request.method == 'POST':
        username =request.POST.get('username', None)
        password =request.POST.get('userpw', None)

        user = authenticate(request, username=username, password=password)
        if not user:
            return render(request, 'user/login.html', {'error':'이름 혹은 패스워드를 확인 해 주세요'}) 
        else:
            auth.login(request, user)
            return redirect('/main')

    elif request.method == 'GET':
        user = request.user.is_authenticated
        if user:
            return redirect('/main')
        else:
            return render(request, 'user/login.html')

login 함수는 사용자의 요청이 GET이면 is_authenticated를 통해 로그인 상태인지 확인하여 로그인 상태라면 main으로 아니라면 login 창을 띄워준다.

사용자 요청이 POST인 경우 사용자로부터 아이디와 비밀번호를 전달받고 authenticate를 통해 db에 저장된 사용자가 있는지 검사하여 사용자가 없거나, 정보가 일치하지 않다면 메시지와 함께 다시 로그인 창을 띄워주고, db에 사용자가 있고 정보가 일치하다면 auth.login으로 사용자의 상태를 로그인으로 전환한 후 main 페이지로 이동시켜준다.

📌 회원가입, 로그인 DTL

#회원가입
{% csrf_token%}
    <form class ="form-signup" method="POST" action="/signup/" name="ProfileForm">
        <div class="contentsWrap">
            <div class="loginWindow">
                <i style="font-size:100px;  " class="fa-brands fa-instagram"></i>
                <input type="text" placeholder="전화번호를 입력해주세요" class="inlineToBlock" id="phone" name="phone">
                <input type="text" placeholder="로그인 시 사용할 아이디를 입력해주세요" class="inlineToBlock" id="username" name="username">
                <input type="password" placeholder="비밀번호" class="inlineToBlock" id="userpw"name="userpw">
                <input type="password" placeholder="비밀번호 재입력 해주세요!" class="inlineToBlock" id="userpw2"name="userpw2">
                <input type="text" placeholder="이름을 입력해주세요" class="inlineToBlock" id="user" name="user">
                <input type="text" placeholder="이메일을 입력해주세요" class="inlineToBlock" id="useremail" name="useremail">
                <!-- <input type="text" placeholder="사진" class="inlineToBlock" id="userimg" name="userimg"> -->
                <input type="text" placeholder="자기 소개말을 입력해주세요" class="inlineToBlock" id="bio" name="bio">
            <button class="inlineToBlock ordinaryLogin unactivatedLoginColor">회원가입</button>
    </form>
        {% if error %}
            <div class="alert alert-danger" role="alert">
                {{ error }}
            </div>
        {% endif %}
  
#로그인
<form class ="form-login" method="POST" action="/login/">
        {% csrf_token %}  
        <div class="contentsWrap">
            <div class="loginWindow">
                <i style="font-size:100px;  " class="fa-brands fa-instagram"></i>
                <input type="text" placeholder="id" class="inlineToBlock" id="username" name="username">
                <input type="password" placeholder="pw" class="inlineToBlock" id="userpw" name="userpw">
            <button class="inlineToBlock ordinaryLogin unactivatedLoginColor" type="submit">로그인</button>
        {% if error %}
            <div class='alert alert-danger' role='alert'>
                {{ error }}
            </div>
        {% endif %}
    </form> 

DTL에서는 POST 일 때 보안을 위해 csrf_token을 사용해야하며 form 태그에서 method를 post, action은 데이터를 전달해줄 경로를 지정해준다.

profile
웹개발 회고록

0개의 댓글