_won_
wonprogrammer
_won_
전체 방문자
오늘
어제
  • 분류 전체보기
    • woncoding
      • TIL
      • WIL
    • source Code
      • Python
      • Programmers
      • BAEKJOON

블로그 메뉴

  • 방명록

티스토리

Github · Wonprogrammer
hELLO · Designed By 정상우.
_won_

wonprogrammer

woncoding/TIL

TIL | 10.27.목 [Django : DRF]

2022. 10. 28. 00:39

- 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
    'woncoding/TIL' 카테고리의 다른 글
    • TIL | 10.31.월 [Django : DRF]
    • TIL | 10.28.금 [Django : DRF]
    • TIL | 10.26.수 [Django : DRF]
    • TIL | 10.25.화 [Django : DRF]
    _won_
    _won_
    Coding Practice blog

    티스토리툴바