[Django] Login

Jin·2021년 9월 20일
0

django

목록 보기
11/14
post-thumbnail

1. Login

  • 로그인은 Session을 Create하는 로직과 같음
  • Django는 우리가 session의 메커니즘에 생각하지 않게끔 도움을 줌
  • 이를 위해 인증에 관한 built-in forms를 제공

1) Authentication

1-1. Authentication Form

  • 사용자 로그인을 위한 form
  • request를 첫번째 인자로 취함

1-2. Authentication data in templates

  • context processors
    • 템플릿이 렌더링 될 때 자동으로 호출 가능한 컨텍스트 데이터 목록
    • 작성된 프로세서는 RequestContext에서 사용 가능한 변수로 포함됨
  • Users
    • 템플릿 RequestContext를 렌더링 할 때, 현재 로그인한 사용자를 나타내는 auth.User 인스턴스 (or 클라이언트가 로그인하지 않은경우 AnonymousUser)는 템플릿 변수 {{ user }}에 저장됨

1-3. get_user()

  • AuthenticationForm의 인스턴스 메서드
  • user_cache는 인스턴스 생성 시에 None으로 할당되며, 유효성 검사를 통과했을 경우 로그인 한 사용자 객체로 할당 됨
  • 인스턴스의 유효성을 먼저 확인하고, 인스턴스가 유효할 때만 user를 제공하려는 구조

참고 : https://docs.djangoproject.com/en/3.2/topics/auth/default/

(1) urls.py

from django.urls import path
from . import views

app_name = 'accounts'
urlpatterns = [
    path('login/', views.login, name='login'),
]

(2) views.py

from django.contrib.auth import login as auth_login
from django.contrib.auth.forms import AuthenticationForm

def login(request):	# GET(로그인 페이지), POST(실제로 실행시켜주는 로직) 요청 둘다 처리
	if request.user.is_authenticated:
    	return redirect('articles:index') # 로그인되어 있으면 인덱스 페이지로 이동
    if request.method == 'POST':
    	form = AtuthenticationForm(request, request.POST)
    	if form.is_valid():
        	auth_login(request, form.get_user())
            return redirect('articles:index')
    else:
    	form = AuthenticationForm()
    context = {
    	'form' : form,
    }
    
    return render(request, 'accounts/login.html', context)

login 함수

login(request, user, backend=None)

  • 현재 세션에 연결하려는 인증 된 사용잦가 있는 경우 login() 함수 필요
  • 사용자를 로그인하며 view 함수에서 사용 됨
  • HttpRequest 객체와 User 객체가 필요
  • django의 session framework를 사용하여 세션에 user의 ID를 저장(==로그인)

2. Logout

유저를 삭제하는게 아닌, Session을 삭제하는것

logout 함수

  • logout(request)
  • HttpRequest 객체를 인자로 받고 반환 값이 없음
  • 사용자가 로그인하지 않은 경우 오류를 발생시키지 않음
  • 현재 요청에 대한 session data를 DB에서 완전히 삭제하고, 클라이언트 쿠키에서도 sessionid가 삭제됨
  • 다른 사람이 동일한 웹 브라우저를 사용해 로그인하고, 이전 사용자의 세션 데이터에 엑세스 하는것을 방지 하기위함
# accounts/views.py
from django.contrib.auth import logout as auth_logout
from django.views.decorators.http import require_POST

@reuqire_POST
def delete(request):
    if request.method == 'POST':
    	auth_logout(request):
    	return redirect('articles:index')
<!-- base.html -->
<form action="{% url 'accounts:logout' %}" method="POST">
  {% csrf_token %}
  <input type="submit" value="Logout">
</form>

3. 로그인 사용자 접근 제한

1) is_authenticaed(attribute)

  • User model의 속성 중 하나
  • 모든 User instance에 대한 항상 True인 읽기 전용 속성
    (AnonymouseUser에 대해서는 항상 False)
  • 사용자가 인증 되어있는지 여부를 알 수 있는 방법
  • 일반적으로 request.user에서 이 속성을 사용, 미들웨어의 'django.contrib.auth.middleware.AuthenticationsMiddleware'를 통과 했는지 확인
  • 권한과는 관련이 없으며, 사용자가 활성화 상태이거나 유효한 세션을 가지고 있는지도 확인하지 않음
{% if request.user.is_authenticated %}
    <h3> Hello, {{ user }} </h3>
{% else % }
<h3> Hi </h3>
      
{% endif % }

2) login_required(decorator)

  • 사용자가 로그인되어 있지 않으면, settings.LOGIN_URL에 설정된 문자열 기반 절대 경로로 redirect 함
    • LOGIN_URL의 기본 값은 '/accounts/login/'
    • 두번째 app 이름을 accounts로 했던 이유 중 하나
  • 사용자가 로그인되어있으면 정상적으로 view 함수를 실행
  • 인증 성공 시 사용자가 redirect 되어야하는 경로는 'next'라는 쿼리 문자열 매개 변수에 저장됨
    • /accounts/login/?next=/articles/create/
from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    if request.method == 'POST':
    	form = AuthenticationForm(request, request.POST)
        if form.is_valid():
        	auth_login(request, form.get_user())
    		return redirect(request.GET.get('next') or 'articels:index'

두 데코레이터 발생하는 문제

비 로그인 상태에서 삭제를 누르고 로그인을 하면 405에러가 발생. 왜? next 쿼리는 GET 방식으로 받는데 두번째 require_POST 데코레이터에 걸리기 때문.

@login_required
@require_POST
def delete(request, pk):
    article = get_object_or_404(Article, pk=pk)
    article.delete()
    return redirect('aritcles:index')

#  해결 코드

@required_POST
def delete(request, pk):
    if request.user.is_authenticated:
   	article = get_object_or_404(ARticle, pk=pk)
    	article.delete()
    return redirect('articles:index')
profile
내가 다시 볼려고 작성하는 블로그. 아직 열심히 공부중입니다 잘못된 내용이 있으면 댓글로 지적 부탁드립니다.

0개의 댓글