[day-37] 인증 로직 구현, FBV

Joohyung Park·2024년 2월 27일
0

[모두연] 오름캠프

목록 보기
69/95

기획

1. 다음 url이 실제 작동하도록 해주세요.
1.1 ''                          : 메인페이지
1.1 'blog/'                     : 블로그 글 목록
1.2 'blog/<int:pk>/'            : 블로그 상세 글 읽기
1.3 'accounts/signup/'          : 회원가입
1.4 'accounts/login/'           : 로그인
1.5 'accounts/logout/'          : 로그아웃
1.6 'accounts/profile/'         : 프로필

기본 구현

앞에서 다룬 내용으로 자세한 설명은 생략하겠다.

  • 프로젝트명 > urls.py 정의
  • main앱 > urls.py 정의
  • main앱 > views.py 정의
  • blog앱 > usrls.py 정의
  • blog앱 > views.py 정의
  • blog앱 > models.py 정의
  • accounts앱 > urls.py 정의
  • accounts앱 > views.py 정의

로그인 로직 구현

accounts > views.py

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.views import LoginView, LogoutView
from django.views.generic import CreateView
from django.shortcuts import render


signup = CreateView.as_view(
    form_class=UserCreationForm,
    template_name="accounts/form.html",
    success_url=settings.LOGIN_URL,
)


login = LoginView.as_view(
    template_name="accounts/form.html",
    # success_url=settings.LOGIN_REDIRECT_URL,
    # next_page=settings.LOGIN_REDIRECT_URL,
)


logout = LogoutView.as_view(
    next_page=settings.LOGOUT_URL,
)


@login_required
def profile(request):
    return render(request, "accounts/profile.html")
  • signup : Django에 정의되어 있는 as_view() 함수를 사용하여 가입 뷰를 생성한다. 마찬가지로 form을 생성하며 템플릿 파일은 accounts 앱의 form.html 템플릿 파일을 사용한다. 가입이 성공하면 settings.py에 정의된 URL로 이동한다.
# settings.py

LOGIN_URL = "/accounts/login/"
LOGOUT_URL = "/accounts/profile/"
  • login : 가입 과정과 동일하다. 특이한 점은, success_url 이 없다는 것인데 이는 내부 로직에서 자동으로 처리되며, 로그인 성공시 사용자가 처음 접근하려고 했던 페이지로 자동으로 리디렉션한다.

    • next_page : Django가 이미 작성해 놓은 view(LoginView 같은) 에서 사용하는 로그인이 성공했을 시 넘어가는 페이지 세팅
    • success_url : 그 이외의 경우
  • logout : 로그아웃 하였을 떄, settings.py에 선언된 LOGOUT_URL로 이동한다.

  • profile : 로그인 한 사용자만 프로필을 보도록 설정하였다. 프로필 페이지에 대한 템플릿은 profile.html 이다.

    • 사용자가 로그인 되어 있지 않은 상태에서 profile 페이지에 접근하면 로그인 페이지로 리디렉트 된다. 이때, 사용자가 원래 접근하려고 했던 페이지의 URL은 쿼리스트링(login/?next=/profile)으로 next 파라미터에 추가되어 함께 전달된다.
    • 따라서, 사용자가 로그인 한 후에는 next 파라미터에 저장된 원래 페이지로 자동 리디렉트 된다.

템플릿 폴더 추가

각 앱의 템플릿이 들어갈 폴더를 선언해준다.

# settings.py

...
"DIRS": [BASE_DIR / "templates"],
...
templates > blog > blog_list.html
templates > blog > blog_details.html
templates > accounts > profile.html
templates > accounts > form.html

게시물 관련 템플릿 구현

  • blog_list.html
  • blog_details.html

인증 관련 템플릿 구현

# profile.html

<h1>개인 프로필 페이지</h1>
<p>{{ user }}</p>

파일 업로드용 폼도 추가하였다.

<form action="" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <table>
        {{ form.as_table }}
    </table>
    <input type="submit">
</form>

슈퍼유저 생성(관리자)

python manage.py createsuperuser

언어 변경(참고)

인증 관련 페이지가 영어로 나오는 것을 한글로 바꿀 수 있다.

# settings.py

LANGUAGE_CODE = "ko-kr"

프로필 > 로그아웃 버튼 추가

# profile.html 수정해서 로그아웃 되게 수정

<h1>개인 프로필 페이지</h1>
<p>{{ user }}</p>

<!-- 로그아웃 버튼 -->
<form action="{% url 'logout' %}" method="post">
  {% csrf_token %}
  <input type="submit" value="로그아웃">
</form>

로그아웃 버튼을 누르면 LOGOUT URL에 의해 로그인 화면으로 돌아간다.

로그인 체크 기능 추가

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.views import LoginView, LogoutView
from django.views.generic import CreateView
from django.shortcuts import render
from django.http import HttpResponse

def logincheck(request):
    print(request.user.is_authenticated)
    print(request.user)
    print(type(request.user))
    print(dir(request.user))
    return render(request, 'accounts/logincheck.html')

미리 선언되어 있는 request 모듈을 사용하여 로그인 여부를 확인할 수 있다.

위의 코드를 실행하면
과 같은 화면이 보여지는데 로그인 하지 않은 상태이다.

logincheck.html 템플릿은 다음과 같이 선언되어 있다.

<p>django.contrib.auth.models.User</p>
<p>{{user}}</p>
<p>{{user.username}}</p>
<p>{{user.email}}</p>
<p>{{user.first_name}}</p>
<p>{{user.last_name}}</p>
<p>{{user.is_staff}}</p>
<p>{{user.is_active}}</p>
<p>{{user.is_superuser}}</p>
<p>{{user.last_login}}</p>
<p>{{user.date_joined}}</p>

없는 정보는 무시된 듯 하다.

(추가) FBV(함수기반 뷰)로 로그인하기

# accounts > views.py

def loginfbv(request):
    if request.method == "POST":
        username = request.POST["username"]
        password = request.POST["password"]
        user = authenticate(request, username=username, password=password)
        print(user)
        print(type(user))
        if user is not None:
            login(request, user)
            return HttpResponse("login 성공")
        else:
            return HttpResponse("login 실패")
    return render(request, "accounts/loginfbv.html")

사용자가 로그인 폼을 제출했다면, 입력한 아이디와 비밀번호를 가져온다. 그 후, 인증에 성공했다면 login 성공 실패했다면 login 실패를 제출하는 부분이다.

# loginfbv.html 템플릿

<form method="post">
    {% csrf_token %}
    <label for="username">아이디</label>
    <input type="text" name="username">
    <label for="password">비밀번호</label>
    <input type="password" name="password">
    <button type="submit">로그인</button>
</form>

profile
익숙해지기 위해 기록합니다

0개의 댓글