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

_·2023년 12월 27일

작정하고 Django 강의

목록 보기
26/44

Bug Fix

※ 수정
views.py에서 AccountUpdateView, AccountDeleteViewcontext_object_name = 'target_user' 추가

update.html, delete.html파일에서 pk=user.pkpk=target_user.pk로 수정

urls.py에서 복수형 s 붙이기 : path('accounts/', include('accountapp.urls')),

GitBash에서 git add ., git commit -m "Bug Fix"입력

Accountapp 을 만들었던 이유

Sign Up       → Create view
              → login View
View info     → Read view
Change info   → Update view
Quit          → 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 → 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 → User 객체 중에서도 UpdateView 같은 경우에는 urls.py에서 path('update/<int:pk> 처럼 int:pk 를 받는데 이 처럼 그 pk에 해당하는 object를 가져오는 것을 의미한다.

그 pk에 해당하는 객체가 지금 request.user (요청하고 있는 사용자)와 같은지 체크

이후 테스트

계정 만들기(4번 계정) -> 새 계정으로 로그인 -> 마이페이지

commit

git add ., git commit -m "django course 27 commit을 통해 커밋한다.

0개의 댓글