요청
: 클라이언트에 의해 전송되는 메시지응답
: 서버에서 응답의로 전송되는 메시지connectionless
: 서버는 요청에 대한 응답을 보낸 후 연결을 끊음stateless
: 연결을 끊는 순간 클라이언트와 서버 간의 통신이 끝나며 상태 정보가 유지되지 않음=> 쿠키
와 세션
을 통해!!!
헨젤과 그레텔
처럼 서버가 사용자의 웹 브라우저에 전송하는작은 데이터 조각
=> 브라우저는 쿠키를 로컬에 저장, 서버 요청시 함께 전송
사이트와 특정 브라우저 사이의
상태를 유지
시키는 것
서버에 저장하는 것을 의미하는것이다. 서버에저장
=>리소스
필요 =>돈
결국 중요하지 않은 데이터는 브라우저에 저장되도록 구현한다.(팝업 하루 안보기 기능)
Session cookie
: 현재 세션이 종료되면 삭제. 브라우저 종료와 함께 삭제Persistent cookies
: 지정된 기간이 지나면 삭제django admin에 들어가면 자동으로 로그인이 된다. 이때 DB의 django-session에 들어가보면 세션이 저장되어 있는 것을 확인할 수 있다.
settings.py에 MIDDLEWARE는 클라이언트와 서버가 통신을 하며 거쳐가는 필터이다.
login(request, user, backend=None)
AuthenticationForm
의인스턴스 메서드
유효성 검사를 통과했을 경우 로그인 한 사용자 객체를 반환
from django.urls import path
from . import views
app_name = 'accounts'
urlpatterns = [
...
path('login/', views.login, name='login'),
]
...
def login(request):
return render(request, 'accounts/login.html')
{% extends 'base.html' %}
{% load django_bootstrap5 %}
{% block body %}
<h1>로그인</h1>
{% endblock body %}
로그인을 위한 built-in form.
ModelForm
이 아닌Form
을 상속 받는다.
...
from django.contrib.auth.forms import AuthenticationForm
...
def login(request):
form = AuthenticationForm()
context={
'form':form,
}
return render(request, 'accounts/login.html', context)
...
{% block body %}
<h1>로그인</h1>
<form action="" method="POST">
{% csrf_token %}
{% bootstrap_form form %}
{% bootstrap_button button_type='submit' content='OK' %}
</form>
{% endblock body %}
...
from django.contrib.auth import login as auth_login # login 이름이 겹쳐서 따로 이름 지정
...
def login(request):
if request.method == "POST":
# AuthenticationForm은 ModelForm이 아님!
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
# 세션에 저장
# login 함수는 request, user 객체를 인자로 받음
# user 객체는 어디있어요? 바로 form에서 인증된 유저 정보를 받을 수 있음
auth_login(request, form.get_user())
# http://127.0.0.1:8000/accounts/login/?next=/articles/1/update/
# request.GET.get('next') : /articles/1/update/
return redirect(request.GET.get("next") or "articles:index")
else:
form = AuthenticationForm()
context = {
"form": form,
}
return render(request, "accounts/login.html", context)
return redirect(request.GET.get("next") or "articles:index")
👉파이선 공식 문서
Boolean Operation 에 따라서 return 값도 결정된다.
여기서는 or이므로 next에 해당하는 요청이 있다면 True이므로 바로 next에 저장된 url 요청이 실행되고, next에 저장된 값이 없다면 False 이므로 뒤에 index 요청이 실행된다.
...
<body>
<div class='container'>
{{ user }} <!-- user 이름을 표현해준다. -->
{% block body %}
{% endblock body %}
{% bootstrap_javascript %}
</div>
</body>
</html>
로그인, 회원가입은 로그아웃 상태에서만 보여야 하므로 조건문을 통해 구현해준다.
<body>
{% if request.user.is_authenticated %}
<span>{{ request.user }}</span>
<a href="{% url 'accounts:logout' %}">로그아웃</a>
{% else %}
<a href="{% url 'accounts:signup' %}">회원가입</a>
<a href="{% url 'accounts:login' %}">로그인</a>
{% endif %}
<div class='container'>
...
로그인 해야 글 작성 가능하도록 서버단에서 작업을 해준다.
...
from django.contrib.auth.decorators import login_required
...
@login_required
def create(request):
if request.method == 'POST':
article_form = ArticleForm(request.POST)
if article_form.is_valid():
article_form.save()
return redirect('articles:index')
else:
article_form = ArticleForm()
context = {
'article_form': article_form
}
return render(request, 'articles/form.html', context=context)
...
from django.contrib.auth import logout as auth_logout
...
def logout(request):
auth_logout(request)
return redirect('articles:index')