본문 바로가기

영어쌤의 놀이방_ 수퍼.코드.파티/리액트와 장고로 회원가입 관리 만들어욤

(5.1) 장고 토큰 인증(Django Token Authentication)_ 영어쌤이 만드는 회원가입, 인증[CRUD] 만들어욤! 리액트와 파이썬 장고

반응형

(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!!!

반응형