우선 프론트엔드는 다른 호스트로 접근하므로 백엔드에서 cors 관련 설정을 해준다. 나는 테스트용으로만 쓸 거라 CORS_ORIGIN_ALLOW_ALL = True
를 해줬다.
자세한 방법은 여기 참고
다음으로 로그인 하는 데에 쓸 html 을 대강 만들어준다.
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>My Website</title>
</head>
<script src="api.js"></script>
<body>
<main>
<h1>Welcome to My Website</h1>
</main>
<form>
<input type="email" name="email" id="email" placeholder="email">
<input type="password" name="password" id="password" placeholder="password">
<!-- type="submit" 으로 해놓으면 버튼을 눌렸을 때 api.js의 fetch 로 가는 것이 아니라 form 으로 가므로 type="button" 이라는 걸 명심할 것 -->
<button type="button" onclick="showLogin()">Button</button>
</form>
<button type="button" onclick="showMock()">Mock API</button>
<button type="button" onclick="showLogout()">logout</button>
</body>
</html>
이 html 의 백은 api.js 이고, 버튼이 눌릴 때마다 해당되는 함수가 실행되도록 만들었다. 함수는 다음과 같다.
showUser() : 전에 만들어놓은 http://127.0.0.1:8000/users/signup/ 에 raw data 를 보내 회원가입
showLogin() : 이메일과 비밀번호를 보내 accessToken 을 발급받아 로컬 스토리지에 저장하고 전달받은 accessToken 으로 json 을 payload 로 로컬 스토리지에 저장하는 로그인 작업
showMock() : acess 토큰을 보내 인증 확인
showLogout() : 로컬 스토리지에 저장된 정보를 모두 지워 로그아웃
먼저 window.onload() 로 페이지가 로딩되는지 확인해준다.
window.onload = () => {
console.log("hello")
}
showUser()
async function showUser() {
// .value 잊지 말기
const email = document.getElementById("email").value
const password = document.getElementById("password").value
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,
})
})
}
email 과 password 를 각각 id 로 가져와주고 fetch 를 통해 signup 페이지로 보내준다. 이때 헤더에는 content-type 이 담기고, 보내는 방식은 전에 지정해주었듯 POST 이다. 그리고 그냥 {"email": email, "password": password}
로 보내면 string 형태로 보내지므로 JSON.strignify() 를 통해 json 형식으로 보내준다.
showLogin()
async function showLogin() {
const email = document.getElementById("email").value
const password = document.getElementById("password").value
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,
})
})
response_json = await response.json() // await 을 걸어줘야 한다. 안 걸면 promise 로 실행되어 다음 코드가 그냥 계속 실행됨
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)
console.log(response_json)
}
위의 함수와 마찬가지로 id를 통해 요소의 값을 가져온 뒤 보내야하는 링크에 fetch 해준다. 이 뒤에 받은 값 - accessToken, refreshToken - 을 json 으로 바꿔준 뒤 loclStorage.setItem() 을 통해 로컬 스토리지에 값을 저장해준다.
다음으로 온 payload 를 json 으로 바꿔준 다음 마찬가지로 로컬 스토리지에 저장해주면
이렇게 저장소에 저장되는 모습을 볼 수 있다.
showMock()
async function showMock() {
const accessToken = localStorage.getItem("access")
const response = await fetch('http://127.0.0.1:8000/users/mock/', {
headers: {
"Authorization": "Bearer " + accessToken,
},
method: 'GET',
})
response_json = await response.json()
console.log(response_json)
}
payload 가 저장된 로컬 스토리지에서 getItem() 을 통해 accessToken 을 가져와 위의 링크로 보내면 유효성 검사를 한 뒤 response 로 {"message": "get 요청"}
을 보내준다.
showLogout()
async function showLogout() {
localStorage.clear();
}
로그아웃은 간단하게 로컬 스토리지의 내용을 모두 지워주면 된다.
로컬 스토리지에 저장된 내용은 쿠키와 다르게 서버가 완전히 종료되기 전까진 지워지지 않기 때문에 저장된 정보를 토대로 새로운 html 을 띄울 수도 있다.