본문 바로가기

코딩일기정리

[21.03.23]Django_사용자기능추가(USER, LOGIN, SIGNUP 등)

2021-03-23

* DJANGO

  1. Django USER, LOGIN, SIGNUP (사용자와 관련된 기능 구축하기 CRUD)
    Authentication system

    ★ HTTP의 특징

    1. 비연결지향 : 서버는 응답 후 접속을 끊는다.
    2. 무상태 : 접속이 끊어지면 클라이언트와 서버 간 통신이 끝나며 상태를 저장하지 않는다.

    즉, 서버와 현재 상태를 공유하기 위해 지속적으로 정보를 포함하여 요청해야하며 이것을 '쿠키'라는 공간에 담아 정보를 주고 받는다.

    ★ 쿠키 : 서버가 사용자의 웹 브라우저에 전송하는 작은 데이터 조각 (재요청할때 쿠키를 함께 보낸다.)

    • 목적
    1. 세션관리 : 로그인, 아이디자동완성, 공지 안보기, 팝업체크 등
    2. 개인화 : 사용자 선호, 테마 등의 세팅
    3. 트래킹 : 사용자 행동, 기록을 분석하는 용도
    • 종류
    1. session cookie : 현재 세션이 종료되면 삭제
    2. permanent cookie : 만료 속성에 지정되어 날짜가 지나면 삭제

    ★ 세션 : 서버에 접속하면 session_id를 준다. 그것을 쿠키에 저장한다.

    ​ django db의 django_session 테이블에 저장된다.

● CRUD (index, login, logout, signup, signout, update(회원정보수정), delete(회원정보삭제) ) 만들기
※ 기본적인 urls.py는 설명에 넣지 않는다.

  1. Index ( 회원정보 보기 )
    superuser나 관리자의 경우에만 회원정보를 볼 수 있는 버튼이 보이고 누르면 회원정보가 나오도록 한다.

    [views.py]

    from django.contrib.auth import get_user_model
    from django.contrib.auth.decorators import login_required
    from django.shortcuts import render, redirect
    
    
  @login_required
  def index(request):
      if request.user.is_superuser:
          users = get_user_model().objects.all()    # model 뒤에 ()에 주의하자!
          context = {
              'users':users,
          }
          return render(request, 'accounts/index.html', context)
      else:
          return redirect('articles:index')
  ```
  1. Login( 로그인하기 )
    회원정보가 있다고 가정하고 로그인 화면에 정보를 기입하면 로그인이 된다.
    서버로부터 sessionid를 받아 장고 db의 django_session 테이블에 저장하고 쿠키 내에 sessionid 저장

    [views.py]

    from django.contrib.auth.forms import AuthenticationForm
    from django.contrib.auth import login as auth_login
    
    def login(request):
        # 로그인 한 경우는 인덱스화면을 보여주도록 설정. (anonymous인지 아닌지만 판별)
        if request.user.is_authenticated:
            return redirect('articles:index')
    
        if request.method == 'POST':
            # AuthenticationForm은 form 클라스를 상속받아 아래와 같은 인자가 필요하다.
            form = AuthenticationForm(request, data=request.POST) 
            if form.is_valid():
                # 아래 함수과정에서 쿠키내 session_id가 만들어지고 django_session내 데이터 형성
                auth_login(request, form.get_user()) 
                # 비로그인 상태에서 글을 create했을때 login 창으로 이동하고 
                # 로그인 시, 바로 create 창으로 이동한다.
                return redirect(request.GET.get('next') or 'articles:index')
        else:
            form = AuthenticationForm()
        context = {
            'form':form,
        }
        return render(request, 'accounts/login.html', context)
  1. Logout
    django 내 buitin 함수 이용

    [views.py]

    from django.contrib.auth import logout as auth_logout
    from django.views.decortators.http import require_POST
    
    @require_POST
    def logout(request):
        auth_logout(request)
        return redirect('articles:index')
  1. Signup ( 회원가입 하기 )
    로그인되어있지 않을때, 회원가입 버튼이 나오고 누르면, 회원가입 화면이 나오고
    정보 기입시, 사용자 db가 만들어지고 로그인이 되는 순서로 작동하도록 한다.

    [views.py]

    from django.contrib.auth.forms import UserCreationForm
    from django.contrib.auth import login as auth_login
    
    def signup(request):
        if request.user.is_authenticated:
            return redirect('articles:index')
    
        if request.method == 'POST':
            # Usercreationform은  modelform으로 아래와 같은 인자를 받아온다.
            form = UserCreationForm(request.POST)
            if form.is_valid():
                user = form.save()
                # db를 만든 후, 그 아이디로 로그인을 한 상태를 유지하도록 한다.
                auth_login(request, user)
                return redirect('articles:index')
        else:
            form = UserCreationForm()
        context = {
            'form':form,
        }
        return render(request, 'accounts/signup.html', context)
  1. Signout( 회원 정보 지우기 )

    [views.py]

    from django.views.decorators.http import require_POST
    
    @require_POST
    def delete(request):
        if request.user.is_authenticated:
            request.user.delete()
        return redirect('articles:index')
  1. Update( 회원 정보 수정하기 )
    로그인 상태에서 회원정보수정하기 버튼을 누르면, 기존 회원정보가 기입된 화면이 나오고
    정보를 수정하면 수정된 정보가 회원정보로 저장되도록 한다.

    [views.py]
    기존 forms인 UserChangeForm을 활용하면 모든 수정 정보란이 다 나타나게 된다.
    사용자의 경우 수정이 필요한 부분만 보이고 수정하면 되기 때문에
    상속후 Custom하여 사용한다.

    상속시, 주의사항 : User의 정보를 가져다 써야하기에 User를 직접 import 하기보다 get_user_model을 활용한다.
    
    from django.contrib.auth import get_user_model
  ```python
  from django.contrib.auth.decorators import login_required
  from ,forms import CustomUserChangeForm

  @login_required
  def update(request):
      if request.method == 'POST':
          form = CustomUserChangeForm(request.POST, instance=request.user)
          if form.is_valid():
              form.save()
              return redirect('articles:index')
      else:
          form = CustomUserChangeForm(instance=request.user)
      context = {
          'form':form,
      }
      return render(request, 'accounts/update.html', context)
  ```
  1. Password change( 회원정보 중 패스워드 바꾸게 하기 )
    update와 비슷하지만, 비밀스런 정보인 암호이기 때문에 다른 form으로 정의되어 있는거 같다.

    [views.py]

    from django.contrib.auth.decorators import login_required
    from django.contrib.auth.forms import SetPasswordForm
    from django.contrib.auth import update_session_auth_hash
    
    @login_required
    def password(request):
        if request.method == 'POST':
            form = SetPasswordForm(request.user, data=request.POST)
            if form.is_valid():
                user = form.save()
                # auth_login(request, user) 이것도 작동은 한다.
                # 다시 로그인 시키기 위해 패스워드 수정에서는 아래 부분을 사용한다
                update_session_auth_hash(request, user)
                return redirect('articles:index')
        else:
            form = SetPasswordForm(request.user)
        context = {
            'form':form,
        }
        return render(request, 'accounts/password.html', context)

※ 이번주 해야할 일
: 블로그 2회 업로드 (완료) 정처기, JAVA 공부 일정 생각하기

※ 한줄 하루 마무리
: 회원가입... 이렇게 어려울줄 알앗다면 성심성의껏 작성할껄......