사전 준비
account 라는 앱을 만들어주자.
$ python manage.py startapp account
settings.py
에 알려주자.# settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog.apps.BlogConfig', 'portfolio.apps.PortfolioConfig', 'account.apps.AccountConfig', ]
보여줄 화면은,
login.html
,signup.html
두개니 만들어주자.이 두 html도 역시 템플릿 상속을 적용 시킬 거니까,
<!-- login.html, signup.html --> {% extends 'base.html' %} {% block contents %} <!-- 내용 작성 --> {% endblock %}
이제 이 안에 넣을 정보는, 회원가입할 때 받을 정보니, form 태그로 보내줘야 할 것이다.
회원가입, 로그인의 일반 적인 형식에 맞추어
form
태그를 작성해보면!<!-- login.html --> {% extends 'base.html' %} {% block contents %} <div class = "container"> <h1> login </h1> <form> Username : <br> <input name = "username" type = "text" value=""> <br> Password : <br> <input name = "password" type = "text" value=""> <br> <br> <input class="btn btn-primary" type="submit" value="Login"> </form> </div> {% endblock %}
<!-- signup.html --> {% extends 'base.html' %} {% block contents %} <div class = "container"> <h1> Sign Up! </h1> <form> Username : <br> <input name = "username" type = "text" value=""> <br> Password : <br> <input name = "password" type = "text" value=""> <br> Confirm Password : <br> <input name = "password" type = "text" value=""> <br> <br> <input class="btn btn-primary" type="submit" value="Sign Up!"> </form> </div> {% endblock %}
회원가입은 비밀번호 확인도 해야되니까!
이제 이 app의 url을 관리하려고 하는데,
저번에 배운 것 처럼, 이걸 urls.py에서 다관리하려고 하지말고 app내서 관리하자.
account 앱에서 urls.py를 만들자.
# account.urls.py # from django.contrib import admin #### 이녀석은 여기서는 필요없겠쥬? admin관리파일 from django.urls import path from . import views #### 이것도 저번에 배운것 urlpatterns = [ path('signup/', views.signup, name = 'signup'), path('login/', views.login, name='login'), ]
이렇게 만든녀석을 다시
secondproject.urls.py
에 알려줘야 한다!# secondproject.urls.py urlpatterns = [ path('admin/', admin.site.urls), path('', blog.views.home, name = "home"), path('blog/', include('blog.urls')), path('portfolio/', portfolio.views.portfolio, name = "portfolio"), path('account/', include('account.urls')), ##### 이녀석 추가해 준다! ] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
자, 그러면 화면을 보여주도록
account.views.py
를 만들 시간!# account.views.py from django.shortcuts import render def signup(request): return render(request, 'signup.html') def login(request): return render(request, 'login.html')
여기까지하고 서버를 킨 후 url로 접속해보면,
http://127.0.0.1:8000/account/signup/
http://127.0.0.1:8000/account/login/
추가로
base.html
로 가서 드랍다운아래에 url을 설정해두자. 귀찮으니까.<!-- base.html --> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="{% url 'portfolio' %}">portfolio</a> <a class="dropdown-item" href="{% url 'login' %}">Login</a> <a class="dropdown-item" href="{% url 'signup' %}">Sign up</a>
시작!
이제부터는
signup.html
에 있는form
태그로 부터 정보를 어떻게 보낼 거냐에 대한 문제를 해결해야한다.자 먼저,
form
태그로 부터 정보를 어디로 보낼 지 부터 만들어 줘야 한다.form 안에
action
으로 이것을 정할 수 있었고,이번에는 정보를 보내는 방식에 있어서 default 인 GET이 아니고,
POST 를 사용해야 한다!
추가적인 속성 값으로,
method = "POST"
와 같이 적어주면 된다.<!-- signup.html --> <form action = "{% url 'signup' %}" method = "POST"> Username : <br> <input name = "username" type = "text" value=""> <br> Password : <br> <input name = "password" type = "text" value=""> <br> Confirm Password : <br> <input name = "password" type = "text" value=""> <br> <br> <input class="btn btn-primary" type="submit" value="Sign up!"> </form>
이 때, 추가로 템플릿 태그로,
{% csrf_token %}
이라고 적어줄 것인데, 이게 뭐냐!
사이트간 요청 위조(Cross Site Request Forgery) 공격을 막기 위한 코드!
난수를 발생시켜 확인하는 코드,, 자세하게는 나중에 ㅠㅜ
<!-- signup.html --> <form action = "{% url 'signup' %}" method = "POST"> {% csrf_token %} Username : <br> <input name = "username" type = "text" value=""> <br> Password : <br> <input name = "password1" type = "text" value=""> <br> Confirm Password : <br> <input name = "password2" type = "text" value=""> <br> <br> <input class="btn btn-primary" type="submit" value="Sign up!"> </form>
이제 이녀석을 보냈고, 이걸 처리해야되니까
views.py
로 가자.자, 여기서 우리는 sign up으로 부터 받은 정보를 가지고 회원가입 절차를 마무리하는 것을 해줘야하는데,
장고에서 이미 사용되고 있는 클래스와 기능을 쓸 것!
그 것을 import 해오는 코드는,
# account.views.py from django.shortcuts import render, redirect ######### 리다이렉트 꼭 가져와서 써야해! from django.contrib.auth.models import User ######## 이녀석 from django.contrib import auth ######## 이녀석!
자 이제 그럼 함수를 만들어 보자!
# account.views.py def signup(request): if request.method == 'POST': if request.POST['password1'] == request.POST['password2']: user = User.objects.create_user(username=request.POST['username'], password.POST['password1']) auth.login(request, user) return redirect('home') return render(request, 'signup.html')
POST 방식의 메서드로 정보가 들어온다면,
그 받은 정보의 pw1 = pw2 인지 확인하고,
맞다면 장고에 내장되어 있는 User 클래스의 메서드를 불러와 user라는 객체를 선언해라.
그리고 로그인해라, 지금 만든 user로
그리고 home로 리다이렉트. 리다이렉트는 URL을 인자로 받는다.
이 함수는 http method 가 post 일 때만 저 if 문이 돌아가고
그렇지 않은 경우 signup.html이 보여지니 성공적이다.
로그인은 너무 쉽다!
<!-- login.html --> <form action = "{% url 'login' %}" method = "POST"> {% csrf_token %} Username : <br> <input name = "username" type = "text" value=""> <br> Password : <br> <input name = "password" type = "text" value=""> <br> <br> <input class="btn btn-primary" type="submit" value="Login!"> </form>
같은 방식으로 적어주자!
그럼 다시 함수를 만들어야겠다.
# account.views.py def login(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = auth.authenticate(request, username = username, password = password) if user is not None: auth.login(request, user) return redirect('home') else: return render(request, 'login.html', {'error' : 'username or password is incorrect.'}) else: return render(request, 'login.html')
이제 그냥 읽어도 읽을 수 있다고 생각하겠다!!
아, 중간에 user =~ 이부분은, 회원이 입력한 정보가 있는 정보인지 확인하는 절차이다.
이 코드를 돌리고나면, None, 혹은 찾은 user 정보, 두가지중 하나의 정보를 출력할 것이다.
그 정보를 가지고 그 밑의 조건문을 돌린다.
정보를 찾았다면 바로 로그인을 하면되고,
아닌 경우 에러를 띄워야 한다.
이번엔 로그아웃 기능!
# account.views.py def logout(request): if request.method == 'POST': auth.logout(request) return redirect('home') return render(request, 'login.html')
그러면 url도 만들어줘야 하니까,
account.urls.py
,secondproject.urls.py
두군데 다 작업을 해주자.# account.urls.py from django.urls import path from . import views urlpatterns = [ path('signup/', views.signup, name = 'signup'), path('login/', views.login, name = 'login'), path('logout/', views.logout, name = 'logout'), ]
# secondproject.urls.py 아 생각해보니까 여긴 이미 되어있네요 :)
그리고
base.html
에 가서 드랍다운에 logout 하나 추가하자.<!-- base.html --> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="{% url 'portfolio' %}">portfolio</a> <a class="dropdown-item" href="{% url 'login' %}">Login</a> <a class="dropdown-item" href="{% url 'signup' %}">Sign up</a> <a class="dropdown-item" href="{% url 'logout' %}">Logout</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#">Something else here</a> </div>
- 이제 서버돌리고 실행하면 잘됩니다!