티스토리 뷰

일상코딩/노트

Django : Authentication system 2

코딩애벌레 2024. 4. 1. 12:16

이전 시간에는 회원가입을 하지 않고 Admin 계정을 통해 로그인, 로그아웃을 예시로 보여주었다. 모두가 Admin이 될 순 없으니 이제 회원가입을 배워보자!



회원가입 : UserCreationForm()

 

: 회원 가입시 사용자 입력 데이터를 받는 built-in ModelForm

앞서 login과 동일하게 html, url, view 정의를 해준다(이제는 반복만 하는 것 같다)
오.. 뭔가 있어보인다.

 

회원가입 페이지까지 확인 되었으니 POST 요청 로직을 마무리하자

Login Form과 달리 reqest를 첫번째 인자로 받지 않는다
아쉽게도 login때 처럼 한번에 되지 않는다

 

저번 시간을 기억해보면 우리는 User 모델을 새롭게 커스텀하려고 가져온 기억이 있을것이다. 그런데 UserCreationForm을 바로 사용할 수 있을까? 

UserCreationForm을 상속해주는 파일에서 model을 User로 받고있는 것을 확인

 

회원가입에 사용하는 UserCreationForm이 기존 유저 모델로 인해 작성된 클래스이기 때문에 대체한 유저 모델로 변경을 해주어야 한다. 이후에 배울 UserChangeForm (유저 정보 변경)역시 model이 User로 설정되어있기 때문에 직접 modelForm을 만들어서 사용해야한다.

이때 User model을 accounts app의 models.py에서 가져오지 않는다

  • get_user_model() : 현재 프로젝트에서 활성화된 사용자 모델(active user model)을 반환하는 함수
  • Django는 필수적으로 User 클래스를 직접 참조하는 대신, get_user_model()을 사용하여 참조하는 것을 강조한다

form을 가져오는 경로가 바뀐 것에 유의하자

 

회원가입하는 경로를 index.html에 추가하면 signup(회원가입)은 완료! 

메인 페이지에 회원가입 링크 넣어주기
회원가입을 진행하고 Database를 확인하니 추가된 모습을 확인

 


회원 탈퇴

 

User 객체를 Delete

: 단순하게 저장된 database에서 user data를 삭제를 진행해주기만 하면 된다

url과 view함수는 위와 같이 정의하면 된다
회원탈퇴 역시 유저 정보에 대한 데이터를 다루기 때문에 csrf을 통한 검증이 필요하다
가입되었던 아이디가 삭제된 모습을 확인

 


회원정보 수정 UserChangeForm()

 

: 회원정보 수정 시 사용자 입력 데이터를 받는 built-in ModelForm

signup과 다른 부분은 instance 데이터를 넘겨준 것

 

instance로 유저 정보를 받아와야 새로 생성되지 않고 제대로 업데이트 된다.

메인페이지에 링크까지 넣어주면 끝!..?

 

인줄 알았으나 회원정보 수정 페이지가 수상하다..

 

UserChangeForm을 상속받아서 사용하게 되면서 User 모델의 모든 정보(fields)까지 출력되어 수정이 가능하기 때문에 일반 사용자들이 접근해서는 안되는 정보는 제외해야한다. 이를 위해 CustomUserChangeForm에서 접근 가능한 field를 수정해주면 된다.

 

바꿀 수 있는 fields는 User 모델의 필드 값을 살펴보면 정의할 수 있다
username, first_name, last_name, email을 선택해서 수정 페이지를 로드해보면 올바르게 반영된 모습

 

페이지는 잘 로드되었으니, 미완성인 update view함수를 마무리하러 가보자.

완성된 view함수, request.POST 넘겨주는 것 잊지 말자
문제없이 수정이 완료되는 모습을 확인


PasswordChangeForm() : 비밀번호 변경

 

: 인증된 사용자의 Session 데이터를 Update 하는 과정

비밀번호 변경 시 사용자 입력 데이터를 받는 built-in Form

앞서 회원정보를 수정하면서 볼 수 있었던 Password 변경 안내
클릭 시 이동되는 url을 확인해보면 따로 정의하지 않았던 경로로 이동되는 모습

 

= > django는 비밀번호 변경 페이지를 회원정보 수정 form에서 별도 안내하는 것을 확인할 수 있고 해당하는 경로는 /user_pk/password/ 임을 확인할 수 있다. 이를 이용하기 위해서 urls.py에 정의할 때, 개인 custom경로를 이용하는 것이아닌 해당 경로로 연결해준다. django에서 제공하는 form을 따라가듯  password 변경 방식을 그대로 따라가는 것과 동일하다.

공부를 꼼꼼하게 했다면 눈치 챘겠지만, 주의해야할 점은 accounts app의 내부 urls는 사용할 수 없다. app의 urls.py는 app_name을 accounts로 정의해놨기 때문에 /user_pk/password/ 를 사용하려면 초기에 배웠던 project 폴더 내의 urls.py를 이용해야 한다.

 

django의 form을 가져와서 사용하는 것으로 이해하면 어디에 import하는지 외우기 쉽다
비밀번호 변경 html 생성
오랜만이라고 까먹으면 안된다. views까지 import 해주는 것 잊지말자
잘 적용된 모습

 

이제 view 함수를 완성시켜주기만 하면 된다. 이때는 user의 정보를 수정할 때처럼 이전 데이터를 가져올 필요는 없다. 평상 시 비밀번호 변경하는 것을 생각하면 이전 비밀번호까지 입력해야 인증되는 것처럼 말이다.

완성된 change_password view 함수 ?

 

= > 비밀번호 변경 시 기존 세션과의 회원 인증 정보가 일치하지 않기 때문에 로그인 상태가 풀리면서 로그아웃

 


update_session_auth_hash(request, user) 

 

: Django에서 제공되는 함수로 암호 변경 시 세션 무효화를 막아주는 함수

암호가 변경되면 새로운 password의 Session Data로 기존 session을 자동으로 갱신하여 로그아웃을 방지

: password를 제외한 User 정보를 변경 시에는 django가 자동 갱신을 해주고 있었다는 것을 의미

 

update_session_auth_hash의 내부를 확인해보면 request와 user를 받아주기 때문에 그대로 넘겨주면 된다


메인페이지를 보면 로그인하지 않은 상태에서 필요없는 탭들이 많다

 

마구마구 기능을 집어넣었는데, 실제 웹 페이지를 생각해보면 로그인 하지 않았을 때와 로그인 했을 때 접근할 수 있는 경로는 당연히 다를 것이다. 로그인 하지 않았는데 로그아웃을 실행할 수 있다던가, 로그인을 했는데 로그인을 또 할 수 있다던가. 실행하면 당연히 오류가 생길 수 밖에 없다. view 함수에서 데이터를 넘겨줄 때 request.user의 데이터를 넘겨줄 때 user의 정보가 없기 때문이다.

이를 막기위해 로그인 사용자에 대해 접근을 제한하는 2가지 방법이 있다.

 

is_authenticated 속성 (attribute)

: 사용자가 인증 되었는지 여부를 알 수 있는 User model의 속성

추가 import 없이 바로 사용가능한 속성

모든 User 인스턴스에 대해 항상 True인 읽기 전용 속성이며, 비인증 사용자에 대해서는 항상 False이다User 인스턴스의

 

1. True/False 값을 이용해 html 내부에서 조건문(if)를 사용하여 로그인한 상태와 비로그인 상태에서 출력되는 링크(요소)를 다르게 설정

로그인 상태와 비로그인 상태의 출력을 분할하여 html 전달

 

2. html에 출력이 되지 않는더라도 사용자가 url을 통해 비정상적인 접근이 가능하기 때문에 view함수에도 인증된 사용자라면 로그인/회원가입 로직을 수행할 수 없도록 설정

= > view함수의 실행 첫 부분에 추가해둔다면 접근 시 이전 페이지로 다시 되돌아가게 설정

url로 직접 접근시에도 위처럼 접근 제한을 걸어두면 redirect에 의해 행동 할 수 없다


login_required 데코레이터 (decorator)

인증된 사용자에 대해서만 view 함수를 실행시키는 데코레이터

비인증 사용자의 경우 /accounts/login/ 주소로 자동 redirect

Django가 제공하는 auth내부의 decorators중 login_required를 import해서 사용할 수 있다

함수 위에 @login_required를 추가하기만 하면 된다

게시글을 작성할 때 로그인 된 유저만 접근 가능한 view 함수위에 작성
accounts도 로그아웃, 탈퇴, 수정, 비밀번호 변경 등은 로그인 되어있는 유저만 접근가능

 

+ 부록

 

회원가입 후 로그인까지 이어서 진행하는 방법

 

: 웹 경험을 생각해보면 회원가입 후 바로 로그인 되는 홈페이지가 있고 아닌 홈페이지도 있다. 우리가 구현한 방식은 최초 회원가입 시 저장 이후 메인 홈페이지로 내보내지는 형태.

: CustomUserCreationForm으로 생성된 유저 데이터를 auth_login 함수에 넣어 바로 실행시켜주면 가능

login과 signup의 차이점은 auth_login인데, signup의 save()를 통과하면서 user 객체가 생성되기 때문에 해당 데이터를 받아서 넘겨주기만 하면 된다
로그인 방식이 추가된 signup view함수

 

 

탈퇴와 함께 기존 사용자의 Session Data 삭제 방법

 

: 사용자 객체 삭제 이후 로그아웃 함수를 호출

탈퇴 후 로그아웃은 불가능 = > 로그아웃이 먼저 진행되면 해당 객체 정보가 없어지기 때문에 탈퇴에 필요한 유저 정보 또한 인식할 수 없기 때문에 탈퇴 진행이 우선

데이터는 삭제되었지만 request에 정보는 담겨있음

 

탈퇴를 하게되면 데이터가 삭제되기 때문에 로그아웃은 자동으로 진행된다. 하지만 위처럼 명시하는 이유가 뭘까?

  • 보안 : 사용자가 탈퇴하면서 해당 세션을 종료해야하는데 데이터 삭제만으로는 세션이 유효하게 남아있을수 있다. 이는 보안에 큰 문제가 될 수 있기 때문에 삭제와 로그아웃은 동일 시 되어야 한다.
  • 사용자 : 탈퇴 이후에도 세션이 남아있어 로그아웃이 활성화 될 수 있다. 이는 사용자에게 혼란을 줄 수 있기 때문에 세션까지 종료를 명확히 해주어야 한다.

의류 사이트에 가입을 하면서 기본 틀이 비슷했기 때문에 굉장히 쉬운 과정인 줄 알았으나 유저 정보 하나만으로도 굉장히 디테일하고 서로 연결된 정보가 많다는 것을 느낀 파트였다. Django가 이정도인데 Spring은 어떨지..

728x90

'일상코딩 > 노트' 카테고리의 다른 글

DB : SQLite (DQL) 명령어  (0) 2024.04.02
DB : 데이터베이스  (1) 2024.04.02
Django : Authentication system 1  (0) 2024.03.29
Django : ORM  (0) 2024.03.21
Django : Model  (0) 2024.03.20
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함