(5.1) 장고 토큰 인증(Django Token Authentication)
안녕하세요? 죠니입니다.
이번 다섯 번째 포스팅은 파이썬_장고 내에서 토큰 인증을 다룰 것 입니다.
지난 포스팅의 마지막에 언급한 리스트를 먼저 상기시켜 볼까요??
1. Implementing authentication
2. 로그인 페이지
3. 등록(register page)
4. React router 사용
5. Dealing with the backend as well~~.(Server Side도 다뤄줘야 합니다.)
6. 5번의 이유는 어느 한 계정으로 로그인 시 해당 계정이 부여받은 권한 밖의 정보는 볼 수 없게 해 줘야 하기 때문이죠.
7. Accounts 라는 Django Backend app(API)을 추가할 것 입니다.
- 지금까지 구현된 기술로는 로그인 과정 없이 바로 서버에 접속해 lead 정보를 입력 및 등록하고 삭제하는 일을 하고 있습니다.
- 그런 활동이 가능한 계정을 따로 두어 관리하는 것이 당연시 되어야 보안을 조금이라도 더 강화할 수 있습니다.
- 그럼 이제 시작해 보겠습니다.
(1) /leadmanager/leads/models.py || user model 추가(계정관리를 위해)
- 위의 이미지와 같이 models.py 파일에 코드를 추가해 줍니다.
1
2
3
4
5
6
7
8
9
|
from django.db import models
from django.contrib.auth.models import User
class Lead(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(max_length=100, unique=True)
message = models.CharField(max_length=500, blank=True)
owner = models.ForeignKey(User, related_name="leads", on_delete=models.CASCADE, null-True)
created_at = models.DateTimeField(auto_now_add=True)
|
cs |
(2) 마이그레이션 해 주기 || 위치: /leadmanager/leads
- 파이썬 코드들이 들어 있는 장고 root 폴더[ /leadmanager/leads ] 내에서 다음의 명령어로 마이그레이션(서비스 갱신이라고 보면 됨)을 해 줍니다.
$ python manage.py makemigrations
- 결과화면
- 다음의 이미지와 같이 0002_lead_owner.py가 생성된 것을 볼 수 있습니다.
- 이제 이 마이그레이션을 실행해 줍니다.
$ python manage.py migrate
- 서버를 재 가동 합니다.
$ python manage.py runserver 0:8000
- 현재의 UI 자체는 아직 다음과 같이 그대로 입니다.
- 여기서 우리의 목표는 인증을 받기 전까진 lead들의 data에 대한 fetch 작업이 불가능하도록 하는 것 입니다.
(3) /leads/api.py 수정
- 우선 일전에 작업한 코드를 먼저 보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
|
from leads.models import Lead
from rest_framework import viewsets, permissions
from .serializers import LeadSerializer
# Lead Viewset
class LeadViewSet(viewsets.ModelViewSet):
queryset = Lead.objects.all()
permission_classes = [
permissions.AllowAny
]
serializer_class = LeadSerializer
|
cs |
- 위의 코드에 따라 별 다른 제한을 두지 않고 무엇이든 가능하도록 했었습니다.
- api.py 파일을다음과 같이 수정해 줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
from leads.models import Lead
from rest_framework import viewsets, permissions
from .serializers import LeadSerializer
# Lead Viewset
class LeadViewSet(viewsets.ModelViewSet):
permission_classes = [
permissions.IsAuthenticated
]
serializer_class = LeadSerializer
def get_queryset(self):
return self.request.user.leads.all()
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
|
cs |
- 결과는 다음과 같습니다.
- 이제수정해준 파이썬 코드에 따라 해당 lead 목록(list)를 볼 수 있는 것은 제한이 걸리게 되었기 때문에 볼 수 없습니다.
- 개발자 모드 콘솔창을 살펴봅니다.
- 403 forbidden 이라는 오류 메세지가 출력됨을 확인할 수 있습니다.
- 다음으로는 우선 UI 상에서 403 error에 대한 처리를 해 줄 수 있도록 합니다.
(4) /src/actions/message.js 코드 추가 작성
- 다른 폴더 내의 messages.js 파일과 혼동하지 않도록 주의하세요!
- 다음과 같이 403 error를 잡을 수 있는 코드를 추가 작성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// messages.js
import { CREATE_MESSAGE, GET_ERRORS } from './types';
// CREATE MESSAGE
export const createMessage = msg => {
return {
type: CREATE_MESSAgE,
payload: msg
};
};
// RETURN ERRORS
export const returnErrors = (msg, status) => {
return {
type: GET_ERRORS,
payload: { msg, status }
}
}
|
cs |
(5) /src/actions/leads.js에 코드 추가 작성
- 바로 전의 단계에서 messages.js 에 에러 메세지를 받는 코드를 추가로 작성해 주었습니다.
- 그렇기에 더이상 leads.js에는 에러메세지에 관한 코드는 필요가 없어졌습니다. 제거 및 간소화 시켜줍니다.
- returnErrors 기능을 가져옵니다.
- 더이상 필요 없는 GET_ERRORS 를 제거합니다.
- 코드 하단의 ADD LEADS 기능의 코드 중 .catch 코드를 수정하여 간소화 시켜 줍니다.
- 방금 전 수정한 .catch 내의 dispatch 코드를 복사해 GET LEADS 에도 똑같이 적용해 줍니다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
import axios from 'axios';
import { createMessage, returnErrors } from './messages';
import { GET_LEADS, DELETE_LEAD, ADD_LEAD } from './types';
// GET LEADS
export const getLeads = () => dispatch => {
axios.get("/api/leads/")
.then(res => {
dispatch({
type: GET_LEADS,
payload: res.data
});
})
.catch(err => dispatch(returnErrors
(err.response.data, err.response.status))
);
};
// DELETE LEAD
export const deleteLeads = (id) => dispatch => {
axios.delete(`/api/leads/${id}/`)
.then(res => {
dispatch(createMessage({ deleteLead: "Lead Deleted" }));
dispatch({
type: DELETE_LEADS,
payload: id
});
})
.catch(err => console.log(err));
};
// ADD LEADS
export const addLeads = () => dispatch => {
axios.post("/api/leads/") // 실제 데이터를 보내기 위한 명령어도 POST입니다. 그러니 post로!
.then(res => {
dispatch(createMessage({ addLead: "Lead Added" }));
dispatch({
type: ADD_LEADS,
payload: res.data
});
})
.catch(err => dispatch(returnErrors
(err.response.data, err.response.status)));
};
|
cs |
- Redux tool을 활용하여 결과를 확인합니다.
- msg 항목 내에 status를 보면 403 error code가 발생되었음을 확인할 수 있습니다.
- postman 에서도 또한 정해준 룰에 따라 더이상 무조건 적으로 lead data를 보여주는 대신 메세지를 하나 보내줍니다.
- 이렇게 해서 우선 data 즉, 정보 자체를 보호하는데는 성공하였습니다.
- 이는 Submit 버튼을 클릭해 등록을 시도하려 할 때에도 동일하게 적용됩니다.
이제 우리에게 필요한 것은 인증을 하도록 해 주는 것 입니다. 그렇게 하기 위해 이제 할 일은
1. Registration(등록) API 만들기: 계정 생성을 위함
2. Login API 만들기
3. TOKEN
- 그리고 우리가 로그인을 할 때 장고 서버로부터 토큰을 받게 될 것 입니다.
- 토큰을 받으면 받은 토큰을 header들과 함께(또는 headers 로부터) 보냅니다.
- 그렇게 하면 lead를 추가, fetch(호출)과 같은 것들을 할 수 있습니다.
결론은 토큰을 받는 인증 플로우를 만들어 주는 것 입니다.
그러면 다음 포스팅으로 뵙겠습니다!
(5.2) 장고 토큰 인증(Django Token Authentication)
Stay tuned for the next episode of Web development by the English teacher JOHNNYCLUB!!!