Django login,logout 세부구현
이전 게시물에 이어 로그인,로그아웃을 좀더 구현 해보고자 한다.
로그인, 로그아웃 세부구현
- 존재하지 않는 아이디 일때 사용자 등록 확인 불가 페이지 띄우기
- 로그인 비밀번호를 틀렸을 때 로그인 실패 페이지 띄우기
- 로그인 성공시 사용자의 이름을 띄우고 로그아웃이 가능하도록 만들기
오류페이지 구현
error.html 수정하기
아이디 오류 , 비밀번호 오류에 따른 err코드를 나누는 것 보다는 POST방식으로 넘어온 데이터들을 가지고 데이터베이스에서 조회가 되지 않으면 "아이디,비밀번호를 다시 확인하세요"라는 문구를 출력하기로 한다. 이를 err코드 2이라고 하고 if문을 더 작성해보자
가장먼저 err코드가 회원가입의 것인지 로그인의 것인지 확인한 후 오류 발생원인을 따져 각 케이스의 오류문구가 출력되도록 한다.
완성된 코드는 아래와 같다.
<!--/accounts/templates/accounts/error.html-->
{% extends 'blog/base.html' %}
{% block page %}
{% if err < 2 %} <!-- 회원가입 오류 -->
<h6>회원가입에 오류가 발생하였습니다 5초후 회원가입페이지로 돌아갑니다.</h6>
{% if err == 0 %}
<p> 중복된 아이디가 존재합니다 </p>
{% else %}
<p> 1차 비밀번호와 2차 비밀번호가 다릅니다. </p>
{% endif %}
<meta http-equiv="refresh" content="5; {% url 'signup' %}">
{% elif err ==2 %} <!-- 로그인 오류 -->
<h6>로그인에 오류가 발생하였습니다 5초후 로그인페이지로 돌아갑니다.</h6>
<p> 아이디가 존재하지 않거나 비밀번호가 틀립니다. 다시 확인해주세요 </p>
<meta http-equiv="refresh" content="5; {% url 'login' %}">
{% endif %}
{% endblock %}
views.py 수정하기
오류에 맞는 err코드를 전송하기 위해선 views.py의 login함수를 아래와 같이 수정해야한다.
이전 코드에서 달라진 점은 아이디 혹은 비밀번호가 잘못 되었을 경우 error.html로 이동,err 를 보내는 것이다.
def login(request):
if request.method == 'POST':
userId = request.POST['userId']
userPw = request.POST['userPw']
user = auth.authenticate(request, username=userId, password=userPw)
if user is not None:
auth.login(request, user)
return redirect('post_list')
else:
return render(request, 'accounts/error.html', {'err' :2})
else:
return render(request, 'accounts/login.html')
로그인 성공시 사용자의 이름을 띄우고 로그아웃이 가능하도록 만들기
로그인이 되어있는 지 확인 하기 위해서는 user 모델의 user.is_authenticated 를 사용한다.
템플릿 언어를 사용하면 html 이 python 변수를 사용 할 수있다고 한다. 내가 지금 헷갈리는 것은....html에 변수와 같은 값을 넘겨줄때면 render 를 사용해 넘겨주고, 넘겨줄때 사용했던 변수 이름으로 html상에서 사용할 수 있었다.
이 경우는 값을 넘길 필요 없이 바로 user의 속성을 가져와서 사용했다. 이거 구글링 좀 해보다가 안되면 스택오버플로우에 질문해봐야겠다.
base.html 수정하기
로그인 유무를 파악하여 로그인시 로그아웃만 가능하게 할 것이며 로그인 되어 있지 않으면 로그인만 가능하도록 바꿔볼 것이다.
기존에 로그인만 가능했던 아래의 코드를 로그인 유무에 따른 동작이 다르게 수정해보자
<a href="{% url 'login' %}" class="top-menu"><span class="glyphicon glyphicon-remove"></span></a>
로그인이 되어있으면 체크표시(glyphicon glyphicon-ok) ,로그인 되어있지 않으면 X표시 (glyphicon glyphicon- remove) 를 나타내고 이를 나누는 것은 user.is_authenticated 이다.
<div class = title-1>
<a href="{% url 'post_draft_list' %}" class="top-menu"><span class="glyphicon glyphicon-edit"></span></a>
<a href="{% url 'post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
<a href="{% url 'signup' %}" class="top-menu"><span class="glyphicon glyphicon-user"></span></a>
{% if user.is_authenticated %}
<a href="{% url 'logout' %}" class="top-menu"><span class="glyphicon glyphicon-ok"></span></a>
{% else %}
<a href="{% url 'login' %}" class="top-menu"><span class="glyphicon glyphicon-remove"></span></a>
{% endif %}
<h1> <a href="http://127.0.0.1:8000/">nyanguk의 블로그</a></h1>
</div>
views.py 의 logout 수정하기
def logout(request):
if request.method == 'POST':
auth.logout(request)
return redirect('post_list')
return render(request, 'accounts/login.html')
로그아웃의 구현을 보면 로그아웃만을 위한 페이지에서 submit 유형의 입력이 들어왔을때 즉,request.method가 POST인 경우에만 로그아웃이 수행되도록 짜여져 있다.
우리는 로그인된 경우 다시 버튼을 누르게 되면 로그아웃이되는, 아이콘(링크 )클릭 만으로 로그아웃을 구현해야한다.
<a href="{% url 'logout' %}" class="top-menu"><span class="glyphicon glyphicon-ok"></span></a>
을 누르면 로그아웃이 되게 해야한다.
아래와 같이 바꾼다면 클릭시 logout함수가 불려지면서 바로 로그아웃이 수행된다.
def logout(request):
auth.logout(request)
return redirect('post_list')