카테고리 없음

스파르타 AI-8기 TIL(12/13)-Django

kimjunki-8 2024. 12. 13. 21:02
URL Namespace
articles, users 두개의 앱을 가지고 있는데, 만약 articles/urls.py에도 hello/  url이 있고, users/urls.py에도 hello/가 있다면 어떻게 될까요?
articles/urls.py
from django.urls import path
from . import views

urlpatterns = [
    ...
    path("hello/", views.hello, name="hello"),
    ...
]

users/urls.py
from django.urls import path
from . import views

urlpatterns = [
    ...
    path("hello/", views.hello, name="hello"),
    ...
]

이럴 때 장고는 namespace란 걸 씁니다.
즉, namespace란 상자 안에 그 안에서 관리를 한다는 뜻입니다.

사용법은 간단합니다

from django.urls import path
from . import views

app_name = "articles"

urlpatterns = [
		...
    path("hello/", views.hello, name="hello"),
    ...
]

이렇게 urlpatterns위에 app_name을 쓰면 됩니다.

{% url 'articles:hello' %}

redirect('articles:hello')

그리고 쓰는 법은 대략 이렇습니다.

하지만 예를 들어 아무리 다르게 이름을 만들어도 만약, 템플릿에 파일이 존재하지 않는다면(예: example.html) 중복되는 이름의 코드가 실행이 됩니다. 

그래서 이러한 방법으로 비슷하게 templates namespace가 있습니다.

쓰는 방법은 조금 다릅니다

여기서 templates 폴더 안에 자신의 앱 이름과 똑같은 폴더를 만들고 그 안에 모든 html 파일을 넣습니다

그리고 이렇게 씁니다. 이러면 특정한 위치 안에서 찾게 됩니다. 즉, html파일이 없을 경우, 중복된 html이 사용되는 대신, 저렇게 특정한 위치에 찾도록 유도하는 것입니다.


Django Auth
인증(Authentication)과 권한(Authorization)을 합쳐서 Auth라고 대개 인증시스템이라고 명명합니다.
   인증(Authentication) : 내가 누구인지를 입증하는 것
   권한(Authorization) : 수행할 수 있는 자격 여부
그전에 쿠키와 세션의 개념이 있다.
HTTP의 특징
1. 비연결지향(Connectionless)
HTTP는 클라이언트가 서버에 요청을 보내고 서버가 응답을 반환한 후, 연결을 종료하는 방식으로 동작합니다.
요청-응답 사이클이 완료되면 연결이 끊어지기 때문에, 다음 요청을 위해서는 새로운 연결이 필요합니다.
이러한 특성은 시스템 자원을 효율적으로 사용하지만, 요청 간의 상태를 유지하지 못한다는 한계가 있습니다.
2. 무상태(Stateless)
HTTP는 상태 정보를 유지하지 않는 프로토콜입니다.
한 번의 요청-응답이 끝나면 서버와 클라이언트는 서로에 대한 정보를 기억하지 않습니다.
즉, 모든 요청은 독립적으로 처리되며, 이전 요청과의 연관성을 알 수 없습니다.
이로 인해 서버는 요청의 맥락(context)을 알 수 없으므로, 클라이언트는 필요한 모든 정보를 매번 요청에 포함해야 합니다.
3. 쿠키와 세션이 없다면?
HTTP가 상태를 유지하지 않기 때문에, 쿠키와 세션이 없다면 사용자는 이전 요청에 대한 정보를 잃게 됩니다.
예를 들어, 로그인 정보를 기억하지 못하므로 사용자는 매 요청마다 다시 인증 과정을 거쳐야 합니다.
이러한 상황은 사용자 경험을 크게 저하시키며, 쿠키와 세션 같은 기술을 통해 상태를 관리하는 방법이 필수적입니다.
쿠키
쿠키(Cookie)에 대한 정리
쿠키(Cookie)는 웹 서버와 브라우저 간의 상태 정보를 저장하고 유지하기 위한 작은 데이터 조각입니다. 쿠키는 웹 애플리케이션에서 다양한 목적으로 사용되며, 특히 세션 관리와 사용자 경험 개선에 필수적입니다.

쿠키의 특징
서버 → 웹 브라우저로 전달
서버가 HTTP 응답 시 Set-Cookie 헤더를 통해 브라우저에게 쿠키를 전달합니다.

Key-Value 형태
데이터는 항상 키(Key)와 값(Value)의 쌍으로 저장됩니다.
예: session_id=abc123

자동으로 서버에 전송
브라우저는 저장된 쿠키를 동일한 서버로 보내는 모든 HTTP 요청의 헤더에 자동으로 포함시킵니다.

유저 로컬에 저장
쿠키는 사용자의 컴퓨터에 저장됩니다.
브라우저가 종료되어도 만료 기한이 설정된 쿠키는 유지됩니다.

쿠키의 주요 용도
세션 관리
로그인 상태 유지 (세션 ID 저장)
장바구니 정보 저장

사용자 설정 유지
테마(다크 모드/라이트 모드)
언어 선택

분석 및 추적
사용자 행동 분석
광고 개인화 (타겟팅 광고)


하지만 쿠키만 있다면,

 


세션
세션(Session)
세션(Session)은 서버 측에서 사용자와의 연결 상태를 관리하기 위한 메커니즘입니다. 사용자가 웹 애플리케이션과 상호작용하는 동안의 데이터를 유지하기 위해 사용되며, 쿠키와 달리 데이터가 서버에 저장됩니다. 세션은 주로 사용자 인증, 장바구니, 일시적인 데이터 저장 등 클라이언트와 서버 간의 상태를 유지하는 데 활용됩니다.

세션의 동작 원리
세션 시작:
사용자가 웹사이트를 방문하면 서버는 세션 ID를 생성합니다.
세션 ID는 고유하며, 사용자와 서버 간의 세션을 식별하는 데 사용됩니다.

세션 ID 저장:
서버는 이 세션 ID를 클라이언트에게 쿠키를 통해 전달하거나 URL에 포함시킵니다.
예: Set-Cookie: sessionid=abc123
클라이언트는 이 세션 ID를 저장하고, 이후 서버에 요청할 때마다 이를 함께 보냅니다.

데이터 저장:
사용자의 데이터를 서버 메모리나 데이터베이스에 저장하며, 세션 ID를 키로 사용하여 데이터를 관리합니다.

세션 유지:
사용자가 서버와 상호작용할 때마다 세션 ID를 통해 데이터를 가져와 사용자를 식별합니다.

세션 종료:
일정 시간 동안 사용자가 활동하지 않거나 명시적으로 로그아웃하면 세션이 종료되고 데이터가 삭제됩니다.


로그인
결국 로그인은 하나의 세션을 만드는 로직이다!
그리고 그것을 위해 Authentication form을 씁니다.

이렇게 똑같이 form을 가져와서 쓰는 것이니 as_p를 씁니다.

그런데 이렇게 되면 회원가입하고 유저를 저장할 테이터 저장소를 가져야 하지 않겠습니까?
하지만 장고는 이미 다 있습니다

데이터 베이스에 들어가서 auth_user로 가면, 이렇게 있는것을 볼 수 있습니다.

즉, 이것을 가지고 상속을 시켜 프로필이나 여러가지 기능을 구현 할 수 있습니다.

장고에는 3가지 권한을 나눔
1. 일반유저(그냥 유저)
2. 스테프(관리자 역)
3. 슈퍼 유저(가장 최고 권한-어드민)

슈퍼 유저를 생성하는 방법은 
1. python manage.py createsuperuser
2. admin을(변경가능) 친다.
3. email(아무거나)친다
3. 패스워드 admin1234(변가능) 친다.
4. 다시 패스워드를 친다.
5. y친다


그러면 이제 로그인도 가능
복잡하다!
하지만 할 수 있다. 먼저 form = AuthenticationForm(data = request.POST)는 사용자의 정보를 보관하는 용도 입니다. 즉, request.POST에 담겨져 있는 데이터를 넣어주는 겁니다(사용자의 정보를 DB에 저장). 그리고 만약 그 정보가 유효하다면(is_valid), user = form.get_user()를 통해 DB에 있는 사용자의 정보를 가져와서, auth_login을 통해 로그인을 시키는 겁니다. 참고로 처음 받는 인자로 request를 받는 이유는 그 안에 쿠키가 있기 때문에 먼저 열어봐야 하기 때문입니다. 그리고 그 request에 다가 어떤 유저의 로그인을 처리할 지 알려주는 겁니다.

완성된 코드와 옆에 세션 코드가 있습니다. 이렇게 로그인을 하면 세션키를 받고, 장고는 이 세션키를 저장하는데, 앞으로 이 유저와 저장한 값의 코드가 같으면 로그인을 허용하는 방식입니다.

그리고 이 세션 아이디를 날리면 로그아웃이 됩니다.


그런데 대부분 로그인 창을 화면 끝 윗부분에 넣습니다. 즉, 모든 창에서 공유되는 바깥쪽 templates에 넣으면 됩니다.

여기서 
<div></div>를 씁니다.
<div></div>는 웹 페이지의 내용을 구획하거나 그룹화하기 위해 사용되는 컨테이너 요소입니다. <div>는 기본적으로 아무런 스타일이나 동작이 적용되지 않은 블록 레벨 요소입니다.
컨테이너로서의 역할
그룹화: 관련 있는 요소들을 묶어 하나의 그룹으로 관리할 수 있습니다.
구조화: HTML 문서를 논리적으로 나누는 데 사용됩니다
그런데 저 class 속성은 특정 HTML 요소에 이름(클래스명)을 부여하여 그룹화하거나 스타일 및 동작을 지정할 때 사용됩니다. <div class="class-name">와 같이 사용되며, 주로 CSS와 JavaScript와 함께 활용됩니다. 즉, 나중에 CSS 적용할 때 저 div안에 있는 코드들도 한꺼번에 적용이 가능하여 이렇게 씁니다.


이제 로그아웃입니다.
로그아웃은 -> 세션 지우기
로그인에 auth_login(사실 login)이 있다면 로그아웃에 logout()이 있습니다.
현재 request에서 가져온 session을 사용하여 DB에서 삭제 

하지만, 이건 DB를 건들이기 때문에 form 작성이 필요하다. 즉, base.html에 적자.

중요한 점.
자 그런데 이렇게도 동작이 되지만, 사실 url로 log_out으로 접근해도 로그아웃이 작동한다. 왜? 이건 POST와 GET의 개념이다.
자 POST는 body에 모든 정보를 담고, GET은 url에 정보를 담는다. 그렇기에 POST에는 csrf_token을 쓰는 것이다.
즉, 사실 url로 log_out으로 접근하면 그것은 더 이상 POST가 아니라, GET 방식으로 접근을 한다는 뜻이다.
다른 말로 저 method가 GET으로 바뀐다는 소리다. 그것을 막기 위해 if request.method == 'POST'를 쓰는 이유이다. 오로지 url이 아닌 UI로만 접근을 가능케 한다는 소리이다.