장고 거북이반 복습(회원 기능)

김서영·2022년 10월 17일
0

장고(django)

목록 보기
10/12
post-custom-banner

장고 거북이반을 수강하며 헷갈렸던 부분들만 모아서 정리해보았다!!

1. 회원 모델 구현

- user model 작성 - abstractuser 살펴보기 - 모델필드들 살펴보기

https://docs.djangoproject.com/en/4.1/topics/auth/customizing/ : 모델 커스터마이징 관련 자료
https://docs.djangoproject.com/en/4.1/ref/models/fields/ : 모델 필드 관련 자료
abstractuser는 필드로 완성 된 전체 User 모델로, 추상 클래스로 상속되어 자신의 프로필 필드와 메서드를 추가 할 수 있다. -> 더 많은 기능!
abstractbaseuser는 인증 기능만 포함되지만 실제 필드는 포함되지 않습니다: 서브클래싱할 때 제공해야 합니다. -> 기본적인 기능! 커스터마이징하기 더 자유롭다??

from unittest.util import _MAX_LENGTH
from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    profile = models.TextField(max_length = 500, blank = True)

- settings.py에 유저 등록

AUTH_USER_MODEL = 'users.User' -> 내가 쓸 유저모델이 뭔지 장고에게 알려주기

- admin 페이지에서 확인하기 - createsuperuser

admin.py에 등록을 하지 않으면 admin페이지에 모델이 나타나지 않는다!!
admin.py에 등록을 해주자!

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

admin.site.register(User, UserAdmin)

2. 회원 가입 구현

https://www.w3schools.com/tags/ref_httpmethods.asp : get, post 관련 자료

- urls 등록

1. 프로젝트의 urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('users/', include('users.urls')),
]

2. users의 urls.py

url의 뒤에 꼭 /붙이기! 이거 안붙이면 post할때 에러난다!

  • views.py 작성
    주소창에 입력해서 나오는 결과는 무조건 GET!
  • template 작성
    https://namu.wiki/w/CSRF : csrf 관련 자료
    csrf은 다른사이트가 우리 사이트인척 하고 요청을 보내는 것을 막기 위해 사용(확실하게 내 사이트라는 것을 알려줌)

3. 로그인 구현

- urls 등록

from django.urls import path
from users import views

app_name = 'users'

urlpatterns = [
    path('signup/', views.signup, name='signup'),
    path('login/', views.login, name='login'),
    path('user/', views.user, name='user'),
    path('profile/<str:username>/', views.profile, name='profile'),
]

❗ url에 스트링이나 인트값이 들어가는 경우 views.py에 키워드 추가해주기

def profile(request, username):
    # user = User.objects.get(username=username) 이것 대신 아래 404를 사용하면 이상한 아이디를 주소창에 쳤을 때 이상한 오류창이 아니라 404창이 뜬다.
    # 예쁜 404창을 만드려면 debug를 false로 해주자!
    user = get_object_or_404(User, username=username)
    context = {
        'user': user
    }
    # html에서 context안에 들어있는 데이터를 이용할 수 있다.
    return render(request, 'profile.html', context)

- views.py 작성

from django.http import HttpResponse
from django.shortcuts import render, redirect
from .models import User #user 모델 불러오기
from django.contrib.auth import authenticate, login as loginsession
from django.shortcuts import get_object_or_404

def signup(request):
    if request.method == "GET":
        return render(request, 'signup.html')
    elif request.method == "POST":
        username = request.POST.get('username')
        # 여기에서 get은 request.Post로 온 데이터 안에있는 것중에서 키값이 username인것을 get해라 
        password = request.POST.get('password')
        passwordcheck = request.POST.get('passwordcheck')
        # print(username, password, passwordcheck) 위 3가지 값들이 잘 가져와 졌는지 확인
        if password == passwordcheck:
            User.objects.create_user(username=username, password=password) # create를 사용하면 비밀번호 자동 해싱 된다.
            return HttpResponse("회원가입 완료!")
        else:
            return HttpResponse("비밀번호 확인이 틀렸습니다.")
    else:
        return HttpResponse("이상한거")

def login(request):
    if request.method == "GET":
        return render(request, 'login.html')
    elif request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        user = authenticate(request, username=username, password=password)
        # authenticate는 인증만 하는 것(진짜 있는 user인지), 없으면 none값 반환
        # login은 아이디와 패스워드로 로그인 세션을 만들어준다.(실제 로그인 과정을 실행)
        if user:
            loginsession(request, user)
            # 원래는 login을 import한거지만 함수명과 같이 오류가 생길수도 있어 import부분에서 as loginsession으로 이름을 변경해줌
            return redirect('users:user')
        else:
            return HttpResponse("로그인 실패")
        
def user(request):
    return HttpResponse(request.user)

def profile(request, username):
    # user = User.objects.get(username=username) 이것 대신 아래 404를 사용하면 이상한 아이디를 주소창에 쳤을 때 이상한 오류창이 아니라 404창이 뜬다.
    # 예쁜 404창을 만드려면 debug를 false로 해주자!
    user = get_object_or_404(User, username=username)
    context = {
        'user': user
    }
    # html에서 context안에 들어있는 데이터를 이용할 수 있다.
    return render(request, 'profile.html', context)

<authenticate와 login의 차이>

  • authenticate는 인증만 하는 것(진짜 있는 user인지), 없으면 none값 반환
  • login은 아이디와 패스워드로 로그인 세션을 만들어준다.(실제 로그인 과정을 실행)

- template 작성

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Signup</title>
</head>
<body>
<h1>회원가입 페이지</h1>
<form action="{% url 'users:signup' %}" method="POST">
    {% csrf_token %}
    <input type="text" name="username" placeholder="username">
    <!-- 여기서 name은 key값이라고 생각하자 -->
    <input type="password" name="password" placeholder="password">
    <input type="password" name="passwordcheck" placeholder="passwordcheck">
    <input type="submit">
</form>    
</body>
</html>
  • username = request.POST.get("username")
    => .get방식으로 키값 name을 받아온다. 값이 없을 때 none값으로 처리(이걸 사용하자!!)
  • username = request.POST["username"]
    => 딕셔너리 방식으로 키값 name을 받아온다. 값이 없을 때 에러가 나는 방식

<render와 redirect의 차이>

  • render : 템플릿을 보여주겠다.
  • redirect : url을 거쳐서 views.py로 왔는데 또 다른 url로 전송할 때 사용

<get과 filter의 차이>

  • get : 특정 하나의 데이터만 가져오겠다.(동일한 조건을 충족하는 여러개가 있을 때 오류가 나기 때문에 pk값이나 유일한 값만 가져와야 한다.)
  • filter : 조건에 부합되는 데이터를 다 가져오겠다.(리스트 형태)

4. 쿠키와 세션을 이용한 로그인 방식에 대한 이해

1. db의 장고 세션에 난수로 새로운 레코드 작성(저장)

2. 키값을 브라우저로 response 보낼 때 같이 전송

3. 브라우저가 키값을 받아서 쿠키에 저장

4. 요청할 때마다 세션 값을 전송

쿠키 허용 하겠냐는 뜻은 브라우저에서 특정 사이트에 접속할 때 그 사이트가 사용하는 저장공간안에 키값을 저장하겠냐
쿠키는 어떤 요청을 하던지 함께 값이 보내진다. 가져온 쿠키에서 세션키값을 비교하여 로그인

- 브라우저 쿠키 확인

  1. 브라우저의 개발자 페이지로 들어가기
  2. 네트워크 클릭
  3. 쿠키 클릭

- db 세션 확인

django session을 확인하면 된다!

5. 비밀번호 해싱 과정에 대한 이해

암호화폐(비트코인), http가 https로 쓰일 때(인증할 때) 등등 사용
결과값이 중복될 가능성이 거의 없다.
입력값을 알 수 없다.
결과값을 알려주고 입력값을 찾을 수 있는 특별한 공식이 없다.
어떤 길이의 데이터도 입력으로 사용될 수 있고, 결과는 정해진 길이로 나온다.
특히 SHA256이라는 해싱 알고리즘은 입력되는 데이터의 길이와 상관없이 항상 256bits를 결과로 준다.(경우의 수가 40억개 정도)
https://brunch.co.kr/@sangjinkang/32#:~:text=%ED%95%B4%EC%8B%B1(Hashing)%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80,Message%20Digest%EB%9D%BC%EA%B3%A0%EB%8F%84%20%ED%91%9C%ED%98%84%ED%95%A9%EB%8B%88%EB%8B%A4. : 암호화와 해싱의 차이점
https://www.rapidsslonline.com/blog/sha1-vs-sha2-vs-sha256-whats-the-difference/ : SHA1과 SHA256의 차이
https://jizard.tistory.com/m/340 : 암호학에서 salt란?(뒤에 뭔가 값을 추가해서 해싱을 하는 것, 장고에서는 secret_key가 이 역할을 한다.)
https://www.kimsungyoo.com/how-django-create-password/ : 장고가 패스워드 생성하는 법
https://namu.wiki/w/%EB%A0%88%EC%9D%B8%EB%B3%B4%EC%9A%B0%20%ED%85%8C%EC%9D%B4%EB%B8%94 : 레인보우 테이블(가장많이 쓰이는 패스워드들의 해시값)

6. 회원 프로필 페이지 구현

- 간단한 프로필 페이지 작성

<404 창 작성방법>

user = User.objects.get(username=username)
user = get_object_or_404(User, username=username)

위의 코드 대신 아래 404 코드를 사용하면 이상한 아이디를 주소창에 쳤을 때 이상한 오류창이 아니라 404창이 뜬다.
예쁜 404창을 만드려면 debug를 false로 해주자!

7. template에 context를 실어보내는 것이 어떤것인지 이해한다.

def profile(request, username):
    # user = User.objects.get(username=username) 이것 대신 아래 404를 사용하면 이상한 아이디를 주소창에 쳤을 때 이상한 오류창이 아니라 404창이 뜬다.
    # 예쁜 404창을 만드려면 debug를 false로 해주자!
    user = get_object_or_404(User, username=username)
    context = {
        'user': user
    }
    # html에서 context안에 들어있는 데이터를 이용할 수 있다.
    return render(request, 'profile.html', context)

딕셔너리 형태의 context를 작성하면 키 벨류값으로 데이터가 이루어지고 html에서 context안에 들어있는 데이터를 이용할 수 있다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>프로필페이지</title>
</head>
<body>

<div>{{ user }}님의 페이지이고 마지막 로그인은 {{ user.last_login }} </div>
<div>지금 로그인한 유저는 {{ request.user }}</div>

{% if user == request.user %}
    <div>내 프로필 페이지</div>
    <button>프로필 편집</button>
{% endif %}    
</body>
</html>

=> {{ user }}가 context의 키값을 대입한 것!!

profile
개발과 지식의 성장을 즐기는 개발자
post-custom-banner

0개의 댓글