작정하고 장고 27강 - Authentication 인증시스템 구축

IkSun·2023년 5월 11일

작정하고 장고

목록 보기
27/46

Bug Fix

[수정]

  • views.py 에서 AccountUpdateView, AccountDeleteViewcontext_object_name = 'target_user' 추가
  • update.html, delete.html 파일에서 pk=user.pk \to pk=target_user.pk 로 수정
  • urls.py 에서 복수형 s 붙이기 : path('accounts/', include('accountapp.urls')),

Accountapp 을 만들었던 이유

  • Sign Up        \to   Create view
                          \to login View
    View info       \to Read view
    Change info   \to Update view
    Quit                \to Delete view

  • 이의 과정들을 거쳐서 Accountapp 을 만들고, Hello World 에 접근하여 아무나 글을 쓸 수 있도록 하였다.

  • 중간에 인증이라는 과정을 넣기 위해서 Accountapp 을 만들었던 것임.

  • HelloWorld 뿐만 아니라 다른 페이지, (게시글, 게시판 등..) -> 인증 과정이 필요

  • 즉, 이 모든것을 만들어주기 위해 먼저 Accountapp 이라는 것을 먼저 말들어줬던 것이다.

인증 과정 만들기

  • hello_world 에 인증을 넣어줄 것임.
  • request 안에 user 라는 객체 안에 is_authenticated 라는 메소드를 사용하여 if else 문으로 인증으로 체크한다
    • header.html 에서 유저가 인증을 했는지 체크하는 부분애도 있다
    • {% if not user.is_authenticated %}
# 로그인이 되어있다면 정상적으로 작동
if request.user.is_authenticated:
   if request.method == "POST":
      temp = request.POST.get('hello_world_input')

      new_hello_world = HelloWorld()

      new_hello_world.text = temp
      new_hello_world.save()

      return HttpResponseRedirect(reverse('accountapp:hello_world'))
   else:

      hello_world_list = HelloWorld.objects.all()
      return render(request, 'accountapp/hello_world.html', context={'hello_world_list': hello_world_list})

# 아닌 경우, 로그인하는 창으로 되돌려 보내기
else:
   return HttpResponseRedirect(reverse('accountapp:login'))

테스트

  • 다음과 같이 url 에 accounts/hello_world 를 입력해도 로그인이 되어있지 않기 때문에 accounts/login 으로 되돌아오는 것을 볼 수 있다.

로그인을 한다면?

  • accounts/hello_world 로 정상적으로 접속된다.
  • hello_world 에 인증을 적용 시킨것 처럼 accountapp 에도 적용해야한다.
  • 어떤 계정으로 로그인을 하지도 않았는데, 그 계정의 정보 수정 페이지로 이동하게 되면 안되기 떄문
  • 하지만, 로그아웃을 했는데도 정보수정 패이지에 들어와지는 문제점 존재 -> 당연히 로그인을 하는 과정을 넣어주어야 함
  • UpdateView 클래스 안에는 get 이라는 메소드가 있다.
  • POST 와 GET 일때 각각 어떻게 행동하는지를 나누어 코드를 작성해주었는데 다음과 같이 get, post 이라는 메소드를 이용해서 각 내부의 행동을 지정해줄 수 있다.
# views.py
class AccountUpdateView(UpdateView):

...

def get(self, *args, **kwargs):
   if self.request.user.is_authenticated: # 로그인이 되어 있다면
      return super().get(*args, **kwargs) # 기존의 방식대로 하고
   else:
      return HttpResponseRedirect(reverse('accountapp:login')) # 로그인 창으로 되돌려 보내기
      
def post(self, *args, **kwargs):
   if self.request.user.is_authenticated: # 로그인이 되어 있다면
      return super().get(*args, **kwargs) # 기존의 방식대로 하고
   else:
      return HttpResponseRedirect(reverse('accountapp:login')) # 로그인 창으로 되돌려 보내기
      
      
# DeleteView 에도 추가

결과

  • accounts/update/3 창으로 가지지 않고 바로 login 창으로 이동하는 것을 볼 수 있다.

문제점

  • accounts/update/3 \to accounts/update/1 로 바꾸면 다른 사용자 계정(test123)의 정보 수정 페이지 및 탈퇴 페이지로 이동할 수 있는 문제점이 발생
    • 3번 계정으로 접속해서 1번 계정을 삭제할 수 있음.

문제점 해결

from django.http import ... HttpResponseForbidden
...
class AccountUpdateView(UpdateView):
   ...
   def get(self, *args, **kwargs):
      if self.request.user.is_authenticated and self.get_object() == self.request.user: # 로그인이 되어 있다면
   

   
class AccountDeleteView(DeleteView):
   ...
   def get(self, *args, **kwargs):
      ...

      else:
         return HttpResponseForbidden() # 금지된 곳에 접근 했다는 것을 보여주는 것이 Forbidden 
         								#-> else 부분 전부 forbidden 으로 수정  
  • 인증 시, 로그인이 되어있어야 하고 그리고

  • self 는 UpdateView 를 가리키고, 이 안에서 현재 사용되고 있는 객체를 말한다.

    • get_object() : model : User \to User 객체 중에서도 UpdateView 같은 경우에는 urls.py 에서 path('update/<int:pk> 처럼 int:pk 를 받는데 이 처럼 그 pk 에 해당하는 object 를 가져오는 것을 의미한다.
  • 그 pk 에 해당하는 객체가 지금 request.user (요청하고 있는 사용자)와 같은지 체크

  • 이후 테스트

    • 계정 만들기(4번 계정) -> 새 계정으로 로그인 -> 마이페이지
  • 3번 ID 로 정수 수정 페이지의 접속을 시도한다면? -> 액세스 거부

가독성의 문제

  • 다음시간에 decorator 를 이용하여 간결하게 표현할 것임.

commit

profile
공부한 것 기록용

0개의 댓글