- Django Rest Framework
DRF 사용자 기능
- 브라우저의 로컬스토리지에 백엔드에서 받은 토큰을 저장할 수 있다. (백엔드)
- 프론트에서 로컬스토리지의 토큰을 헤더에 실어서 백엔드로 보낼수 있다.
[Frontend]
- 초기 설정 (https://wonprogrammer.tistory.com/76 참고)
- 1) 새로운 front파일을 만들어 사용자에게 보여줄 .html 파일을 만들어 준 뒤 .js 파일을 넣어준다.
- 2-1) 백엔드 서버를 불러올 .js 파일을 만들어 준다.
- 2-1-1) 불러오기 전, 다른 도메인에서 요청을 보낼땐 별도의 허용이 필요하다. 따라서 백엔드 서버에서 cors 허용해주기
- 2-1-2) pip install django-cors-headers
- 2-1-3) 허용한 cors → Insatalled App에 선언
- 2-1-4) MIDDLEWARE 에 'corsheaders.middleware.CorsMiddleware' 선언
- 2-1-5) 마지막에 추후 Domain에 적용하기 위해 → CORS_ALLOW_ALL_ORIGINS = True 추가해주기
[회원가입 / 로그인]
우리는 사용자 정보를 local storage에 저장된 Token으로 관리 하기때문에
사용자가 서버를 이용할 email과 비밀번호를 서버에 POST 요청으로 보내 회원가입을 한 뒤,
가입한 email과 비밀번호를 이용해 로그인 하면 refresh Token과 access Token이 local storage에 저장된다.
+ 회원가입이 되지 않은 계정은 POST 요청을 보내더라도 Unauthorized Error가 뜨게된다 (401 Error)
+ access Token이 만료되면 가입한 email과 비밀번호 정보를 가진refresh Token을 이용해 다시 로그인을 하여 재발급 받아야 한다.
- 회원가입 과정
Frontend 초기 설정 방법을 참고해서
- signup.html : 회원가입 페이지를 만들어준다.
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>signup page</title>
<script src="api.js"></script>
</head>
<body>
<h1>회원가입 페이지</h1>
<!-- form 기능은 json 형태로 보내지지 않기 때문에 form 형태만 쓰고 기능은 쓰지 않는다. -->
<form>
<input type="email" name="email" id="email" placeholder="email" />
<input type="password" name="password" id="password" placeholder="password" />
<!-- button type의 submit은 form태그를 get 방식으로 보내주기 때문에 쓰지 않고, 단순히 눌러지는 기능만 필요하기 때문에 button 만 선언 -->
<button type="button" onclick="handleSignin()"> 제출 </button>
</form>
</body>
- api.js : 백엔드 - 프론트엔드 서버를 연결해 준다.
async function handleSignin(){
// 변하지 않는 변수 선언 const
const email = document.getElementById("email").value
const password = document.getElementById("password").value
// 서버 확인용 log
console.log(email, password)
// 백엔드에서 연결할 서버 url 주소 설정
const response = await fetch('http://127.0.0.1:8000/users/signup/', {
// Token header 부분을 json 타입으로 바꿔준다.
headers: {
'content-type':'application/json',
},
method:'POST',
// json 형태로 보내줘야 하므로 : JSON.stringify 설정
body: JSON.stringify({
"email":email,
"password":password
})
})
console.log(response)
}
- 로그인 과정
- login.html : 로그인 페이지를 만들어 준다.
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>login page</title>
<script src="api.js"></script>
</head>
<body>
<h1>로그인 페이지</h1>
<!-- form 기능은 json 형태로 보내지지 않기 때문에 form 형태만 쓰고 기능은 쓰지 않는다. -->
<form>
<input type="email" name="email" id="email" placeholder="email" />
<input type="password" name="password" id="password" placeholder="password" />
<!-- button type의 submit은 form태그를 get 방식으로 보내주기 때문에 쓰지 않고, 단순히 눌러지는 기능만 필요하기 때문에 button 만 선언 -->
<button type="button" onclick="handleLogin()"> 제출 </button>
</form>
<button type="button" onclick="handleMock()"> mock api </button>
<button type="button" onclick="handleLogout()"> 로그아웃 </button>
</body>
- 1) handleLogin : 회원가입이 되어있는 계정으로 refresh Token으로 로그인 → access Token 재발급 및 로그인
- 2) handleMock : header에 access Token실어서 보내고 보낸 access Token으로 로그인 된 사용지인지 확인 할 수 있다.
- 3) handleLogout : local storage에 저장된 payload / refresh Token / access Token 모두 삭제해 준다.
↓
- api.js : 백엔드 - 프론트엔드 서버를 연결해 준다.
1) handleLogin
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
})
})
// json 형태로 읽을 수 있게 바꿔줘
const response_json = await response.json()
console.log(response_json)
// 로그인 한 사용자의 정보를 -> localStorage에 무슨 key 값으로 저장할거야? : response_json.access값 저장
localStorage.setItem("access", response_json.access);
// 로그인 한 사용자의 정보를 -> localStorage에 무슨 key 값으로 저장할거야? : response_json.refresh값 저장
localStorage.setItem("refresh", response_json.refresh);
// payload 값을 json 형태로 보여주기
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);
}
2) handleMock
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)
}
3) handleLogout
async function handleLogout(){
// local storage에 저장된 아래 정보들을 모두 지워주면 됨 : removeItem
localStorage.removeItem("access")
localStorage.removeItem("refresh")
localStorage.removeItem("payload")
}
[Homepage에 로그인된 사용자 email 띄우기]
- index.html : 연결된 index.js를 이용해 서버 접속시 첫 Homepage에 사용자 email 띄우기
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home page</title>
<script src="index.js"></script>
</head>
<body>
<h1>Home page</h1>
<div id="intro"></div>
</body>
- index.js : 로그인된 회원의 email을 불러온다.
window.onload = () => {
// 로그인된 사용자의 payload속 정보 중 email 가져온다.
const payload = localStorage.getItem("payload");
const payload_parse = JSON.parse(payload)
console.log(payload_parse.email)
// index.html에 있는 id='intro'에 ById별로 email을 보여준다
const intro = document.getElementById('intro')
intro.innerText = payload_parse.email
}
'woncoding > TIL' 카테고리의 다른 글
| TIL | 10.31.월 [Django : DRF] (0) | 2022.10.31 |
|---|---|
| TIL | 10.28.금 [Django : DRF] (0) | 2022.10.31 |
| TIL | 10.26.수 [Django : DRF] (0) | 2022.10.27 |
| TIL | 10.25.화 [Django : DRF] (0) | 2022.10.25 |
| TIL | 10.24.월 [Django : DRF] (0) | 2022.10.24 |