✔️ Django 로그인, 로그아웃에 관한 내용은 간략하게 다뤄보았다. 하지만 정말 디자인이 하나도 되어있지 않은 input 텍스트만으로 구현을 했기 때문에 부족해보이며 완성되지 않아보인다. 이번에는 로그인폼에 디자인 을 입히면서 로그인 로직을 조금 수정 해 보려고 한다.
✔️ 우리가 디자이너가 아닌이상 디자인을 구상하거나 색상을 잘 배치하는 것은 개발자에게 어려운 일이다. 이러한 어려움을 해결해 줄 수 있는 것이 부트스트랩인데 부트스트랩을 유/무료로 제공하는 Creative Tim이라는 곳을 알게되어 이곳에서 디자인을 가져와 보려고 한다.
Creative Tim > Impact Design System
✔️ 단, 무료로 사용하기 위해서 아래와 같은 저작권 관련 소스 추가하여야한다.
✔️ 위의 링크에서 부트스트랩에 대한 소스를 다운로드 받은 후 아래와 같이 Fonts, Icons, Page, Argon 등의 플러그인을 추가해 주었다.
<!-- Fonts -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700">
<!-- Icons -->
<link rel="stylesheet" href="{% static 'assets/vendor/nucleo/css/nucleo.css' %}" type="text/css">
<link rel="stylesheet" href="{% static 'assets/vendor/@fortawesome/fontawesome-free/css/all.min.css' %}" type="text/css">
<!-- Page plugins -->
<link rel="stylesheet" href="{% static 'assets/vendor/fullcalendar/dist/fullcalendar.min.css' %}">
<link rel="stylesheet" href="{% static 'assets/vendor/sweetalert2/dist/sweetalert2.min.css' %}">
<!-- Argon CSS -->
<link rel="stylesheet" href="{% static 'css/dashboard.css' %}" type="text/css">
✔️ 이제 로그인 Form 관련 HTML소스를 가져와 로그인 화면이 제대로 나오는 지 확인하여 보자. 아직은 서버와의 통신은 신경쓰지 말고 디자인만 확인하도록 하겠다.
✔️ 이전 로그인 구현 시 {{ form.as_p }}으로 서버에서 보내주는 Form 그대로 사용하였었다. 하지만 이번에는 보내주는 Form에서 input 텍스트 컨트롤만 그대로 꺼내어 사용하며 그 input 텍스트에 디자인을 입히려고 한다.
변경 전
<h2>로그인</h2>
<h4>{% if msg %}{{ msg }}{% endif %}</h4>
<form action="login" method="post">
{% csrf_token %}{{ form.as_p }}
<button class="btn btn-outline-secondary" type="submit">드가쟈~!</button>
</form>
변경 후
<div class="text-center mb-4">
<small>이메일 로그인</small>
</div>
{% if msg %}
<p class="text-center text-sm text-danger">{{ msg }}</p>
{% endif %}
{% if is_ok or user.is_authenticated %}
<p class="text-center text-sm text-success">로그인 성공({{ user.username }}) <a class="text-primary" href="{% url 'logout' %}">로그아웃</a></p>
{% else %}
<form method="post">
{% csrf_token %}
<div class="form-group mb-3">
<div class="input-group input-group-merge input-group-alternative">
<div class="input-group-prepend">
<span class="input-group-text"><i class="ni ni-user-run"></i></span>
</div>
{{ form.username }}
</div>
</div>
<div class="form-group">
<div class="input-group input-group-merge input-group-alternative">
<div class="input-group-prepend">
<span class="input-group-text"><i class="ni ni-lock-circle-open"></i></span>
</div>
{{ form.password }}
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary my-4">로그인</button>
</div>
</form>
✔️ 서버에서 보내온 form에서 username
과 password
를 꺼내서 사용하는 것이다. 이렇게 사용하게 되면 다른 html 요소에 클래스를 넣어 디자인을 조작할 수 있다. 하지만 이렇게만 하면 input 텍스트는 그대로 서버에서 보내온 form을 사용하는 것이기 때문에 세밀한 조작은 서버 자체에서 해줘야 한다.
def login_view(request):
msg = None
is_ok = False
if request.method == "POST":
form = AuthenticationForm(request, request.POST)
template = "login.html"
if form.is_valid():
username = form.cleaned_data.get("username")
raw_password = form.cleaned_data.get("password")
user = authenticate(username=username, password=raw_password)
if user is not None:
login(request, user)
template = "index.html"
is_ok = True
else:
msg = "올바른 유저ID와 패스워드를 입력하세요."
else:
form = AuthenticationForm()
# Form으로 보내는 요소의 옵션 조작하기
for visible in form.visible_fields():
visible.field.widget.attrs["placeholder"] = "유저ID" if visible.name == "username" else "패스워드"
visible.field.widget.attrs["class"] = "form-control"
return render(request, "login.html", {"form": form, "msg": msg, "is_ok": is_ok})
✔️ 위의 소스에서 visible_fields() 함수를 사용하여 반복문 루프를 통해 해당 요소에 placeholder와 class를 추가하여주며 클라이언트에서 렌더링될 때 원하는 형태로 조작을 해 주었다.
visible_fields() : 보이는 필드가 무엇이 있는지 리스트로 반환
✔️ 결과를 확인해 보면 서버에서 조작한 placeholder와 클래스가 입혀진 input 텍스트 박스가 디자인이 변경된 것을 확인 할 수 있다.
✔️ 현재는 username과 password를 사용하였는데, 번들로 제공하는 AuthenticationForm은 username와 password 두개의 필드만 존재하기 때문에 만약에 계정을 email을 사용하게 되면 커스텀 Form을 만들어야 한다.
❗️ csrf_token 태그를 사용하는 이유!!
csrf_token은 일종의 방어장치이며, 해당 페이지에서의 요청으로만 요청을 처리할 수 있게 하는 기능을 가지고 있다. 또한 요청이 한 번 이라도 성공이 되면 csrf_token은 만료가 되기 때문에 중복요청을 방지할 수 있다.