■ JITHub 개발일지 42일차
□ TIL(Today I Learned) ::
파이썬, Django rest framework, front-end
- 파이썬 drf를 활용해서 기본적인 user 환경을 만들어보고, frontend index화면을 javascript를 활용하여 연결해보았다.
- 로그인 화면에서 from 태그를 이용하여 사용자로부터 내용을 입력받고, 특정 명령을 줄 때에는 button을 활용하였다. 이 때, onclick 옵션을 통해 javascript에서 정의해준 function을 불러오게 하였다.
...
<body>
<h1>로그인 페이지</h1>
<form>
<input type="email" name="email" id="email" placeholder="email">
<input type="password" name="password" id="password" placeholder="password">
<button type="button" onclick="handleLogin()">제출</button>
</form>
<button type="button" onclick="handleMock()">모크 api</button>
<button type="button" onclick="handleLogout()">로그아웃</button>
</body>
- 자바스크립트에서 페이지를 잘 불러왔는지 확인할 때에는 아래와 같이 window.onload를 사용했다. 이 때 arrow function을 사용하는데 아직 익숙하지 않다.
window.onload = () => {
console.log("로딩완료")
}
- 회원가입 기능은 아래와 같이 작성했다.
- 비동기 처리를 위해 async/await를 사용했다. (※ 참고 링크)
- form에서 작성된 data를 가져오기 위해서 document.getElementById를 사용한다. getElementById는 하나의 값만 가져올 수 있다. 여러개의 값은 getElementsByName(getElementsByTagName, getElementsByClassName 등) 등을 사용해야 한다. 또, 해당 값으로 읽어오기 위해서 .value를 뒤에 붙여주어야 해당값으로 읽어오게 된다.
- await를 통해 결과값을 받을 때까지 기다려준 후 다음라인으로 넘어간다. 이 때 주소는 .../users/signup/ 으로 해준다.
- headers에는 content-type, method는 POST, body는 JSON.Stringify를 통해 직렬화 시켜주고, email과 password를 넣어 보내주는 것으로 signup기능을 구성했다.
async function handleSignup(){
const email = document.getElementById("email").value
const password = document.getElementById("password").value
console.log(email, password)
const response = await fetch('http://127.0.0.1:8000/users/signup/', {
headers:{
'content-type':'application/json',
},
method:'POST',
body:JSON.stringify({
"email":email,
"password":password
})
})
console.log(response)
}
- 로그인 기능은 유사하지만 좀 다르다.
async function handleLogin(){
const email = document.getElementById("email").value
const password = document.getElementById("password").value
console.log(email, password)
const response = await fetch('http://127.0.0.1:8000/users/api/token/', {
headers:{
'content-type':'application/json',
},
method:'POST',
body:JSON.stringify({
"email":email,
"password":password
})
})
const response_json = await response.json()
console.log(response_json)
localStorage.setItem("access", response_json.access);
localStorage.setItem("refresh", response_json.refresh);
const base64Url = response_json.access.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
localStorage.setItem("payload", jsonPayload);
}
- 로그인이 완료되면response에 access 토큰과 refresh 토큰이 생긴다. 위의 코드 중 아래의 표현에서는 json형태로 바꾸어 response_json에 넣어준다.
const response_json = await response.json()
- 그리고 response_json에서 access 토큰, refresh 토큰을 각각 꺼내어 localStorage.setItem을 사용하여 localStorage에 access 토큰과 refresh 토큰을 넣어준다. (*localStorage에서 값을 가져올 경우에는 getItem을 사용한다.)
localStorage.setItem("access", response_json.access);
localStorage.setItem("refresh", response_json.refresh);
- 마지막으로 paload를 전달하기 위해 아래의 코드를 추가해주었다. (이 때에는 코드가 복잡해서 그냥 붙여넣었다.)
response_json의 access 토큰에서 .을 기준으로 두번째 항을 base64Url에 넣고, 두 번째 줄에서는 base64에 base64Url을 넣고 문자를 치환해준다. 그 아래줄에서는 코드를 해석한 결과를 jsonPayload에 넣어준다.
const base64Url = response_json.access.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
localStorage.setItem("payload", jsonPayload);
- Mock 기능은 간단하게 아래처럼 구현했다.
# users/views.py
class mockView(APIView):
permission_classes = [permissions.IsAuthenticated]
def get(self, request):
user = request.user
user.is_admin = True
user.save()
return Response("get 요청")
async function handleMock(){
const response = await fetch('http://127.0.0.1:8000/users/mock/', {
headers:{
"Authorization":"Bearer " + localStorage.getItem("access")
},
method:'GET',
})
console.log(response)
}
- logout 기능의 경우 localstorage.removeItem을 사용할 수도 있지만 이 경우에는 삭제할 항목들을 각각 넣어주어야 한다. 더 좋은 방법이 있을 것 같아 구글링해보니, localStorage에 있는 모든 내용을 삭제하려면 간단하게 clear()를 사용할 수도 있었다. localStorage에 있는 모든 내용을 삭제했을 때 문제가 되는 것이 있을지, 확인은 필요해보인다.
async function handleLogout(){
localStorage.clear();
// localStorage.removeItem("access", "refresh", "payload");
}
'DEV > Web 개발' 카테고리의 다른 글
Web 개발 :: 노래 추천 서비스 프로젝트 SA (0) | 2022.11.02 |
---|---|
Web 개발 :: 파이썬 Django Rest Framework(9) _ 게시글 상세, 수정, 삭제 (0) | 2022.11.02 |
Web 개발 :: 파이썬 Django Rest Framework(8) _ 게시글 생성 (0) | 2022.11.01 |
Web 개발 :: django, get_object_or_404, get_list_or_404_TIL#41 (0) | 2022.10.31 |
Web 개발 :: 파이썬 Django Rest Framework(7) _ 회원가입, 로그인(Front-End) (0) | 2022.10.31 |
댓글