1. 토큰방식 로그인 vs 세션방식 로그인

(1) 세션방식 로그인

로그인을 하면 백엔드에서 쿠키를 돌려주고 세션을 만든다. 로그인할 때마다 쿠키와 세션을 비교하며 확인한다.

  • 완전히 stateless하지 않다.(연결이 지속적이지 않다.)
  • 많은 사람들이 접속해있는 경우 db에 부하가 생기기 좋은 구조
  • 한 계정으로 여러곳에서 로그인 하기 어렵다.

(2) 토큰방식 로그인

로그인을 하면 백엔드에서 사용자의 정보가 담긴 토큰을 돌려보내준다. 이를 쿠키 대신에 로컬스토리지라는 곳에 저장한다.(주민등록증같은 느낌)

  • 토큰 하나하나마다 확인을 거치지 않아도 된다.
  • 기기별로 토큰을 발급해주기 때문에 여러곳에서 로그인하기 좋다.
  • stateless 하다.

토큰&세션 관련 자료 : https://www.geeksforgeeks.org/session-vs-token-based-authentication/

2. 로컬스토리지 vs 쿠키

(1) 쿠키

  • 이름, 벨류값, 도메인, 경로, 만료일 등등이 담겨있다.
  • 매번 모든 요청에 실려보내진다.
  • 데이터 사이즈 : 4096 바이트
  • 만료일이 있다.
  • 설정하기 어렵다.(코드가 길어진다.)

(2) 로컬스토리지

  • 키벨류만 담겨있다.
  • 데이터 사이즈 : 5메가 바이트
  • 만료일이 없다.
  • 설정하기 쉽다.(코드가 짧다. 2~3줄?)

3. drf에서 jwt사용하기 (simplejwt)

simple jwt 관련 자료 : https://django-rest-framework-simplejwt.readthedocs.io/en/latest/getting_started.html
jwt 저장 관련 자료 : https://velog.io/@0307kwon/JWT%EB%8A%94-%EC%96%B4%EB%94%94%EC%97%90-%EC%A0%80%EC%9E%A5%ED%95%B4%EC%95%BC%ED%95%A0%EA%B9%8C-localStorage-vs-cookie

  1. 필요한 모듈 설치

    pip install djangorestframework-simplejwt
    pip install djangorestframework
    pip install django

  2. settings.py에 추가

INSTALLED_APPS = [
    'rest_framework',
    'user',
    'rest_framework_simplejwt',  
]
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (

        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}
  1. urls.py에 추가
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

이렇게 하고 포스트맨에서 로그인 해보자!!

views.py에서 에러처리를 따로 안해도 TokenObtainPairView가 view에서 자체적으로 만들어준다.

제대로 로그인을 해보면 아래와 같은 결과가 나온다.

4. jwt 정보 확인해보기

jwt 공식 사이트 : https://jwt.io/

jwt 공식 사이트에 토큰을 넣어보자!
결과값이 3가지로 나뉘어서 나온다.

(1) access token

- Header: 어떤 알고리즘으로 해싱이 되었는지, 어떤 타입인지

- PayLoad : 실제 데이터(토큰타입, 만료날짜, 유니크아이디, 유저아이디)

- Verify Signiture : 주민등록증 인감 부분이라고 생각하자

-> 처음 토큰만 입력했을 때는 인증이 안된 상태라 invalid라고 뜨는데 이것을 인증을 하려면 settings.py에 있는 secret key를 입력해야한다.
그리고 이 secret key는 .env파일로 관리를 해야한다.

(2) refresh token

결과값은 토큰 타입만 다르고 나머지는 같다!

(3) access와 refresh의 차이

- access

만료가 된다. 만료가 되면 자동으로 로그아웃
누군가가 탈취를 하면 서버쪽에서 삭제를 시킬 수 없다.
만료일은 내가 변경할 수 있다.

- refresh

access가 만료가 되면 refresh를 이용해 재발급 받을 수 있다.

5. custom user 만들고 등록하기

유저 커스터마이징 관련 자료 : https://docs.djangoproject.com/en/4.1/topics/auth/customizing/

from django.db import models
from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser
)


class UserManager(BaseUserManager):
    def create_user(self, email, password=None):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        user = self.create_user(
            email,
            password=password,
        )
        user.is_admin = True
        user.save(using=self._db)
        return user


class User(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin

- BaseUserManager

핼퍼 클래스로 필수적으로 있어야 한다!
핼퍼 클래스에는 추가적으로 메소드들이 정의되어 있고, db와 송신하는 것들이 저장되어 있다.
핼퍼 클래스가 없으면 오류가 발생한다.

올려놓은 코드는 장고 공식 사이트에서 커스텀유저용으로 올라온것을 가져온 것인데 모든 것들이 필수 요소들이니 빼먹지 말아야 한다!!!

6. custom user 어드민 만들기

유저 커스터마이징 관련 자료 : https://docs.djangoproject.com/en/4.1/topics/auth/customizing/

- admin.py에 추가

from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.core.exceptions import ValidationError
from user.models import User


class UserCreationForm(forms.ModelForm):
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ('email',)

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = User
        fields = ('email', 'password', 'is_active', 'is_admin')


class UserAdmin(BaseUserAdmin):
    form = UserChangeForm
    add_form = UserCreationForm

    list_display = ('email', 'is_admin')
    list_filter = ('is_admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Permissions', {'fields': ('is_admin',)}),
    )

    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2'),
        }),
    )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()



admin.site.register (User, UserAdmin)

admin.site.unregister(Group)

수정할 때 trailing 콤마 주의하기!! 콤마 안붙이면 오류난당~~
이렇게 작성하면 비밀번호 해싱도 되고, 이메일로 유저 검색도 가능하다!!

7. 회원가입과 로그인을 위한 urls.py와 views.py

- urls.py

from django.urls import path, include
from user import views
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('signup/', views.UserView.as_view(), name='user_view'),
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

- view.py

  1. 회원가입
from rest_framework.views import APIView
from rest_framework import status
from rest_framework.response import Response
from user.serializers import UserSerializer

class UserView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({"message":"가입완료!"}, status=status.HTTP_201_CREATED)
        else:
            return Response({"message":f"${serializer.errors}"}, status=status.HTTP_400_BAD_REQUEST)

- serializers.py

1. 기본

from rest_framework import serializers
from user.models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"


기본만큼만 하면 회원가입이 되긴 되지만 비밀번호 해싱이 안된채로 회원가입이 되어서 로그인이 안된다!
이를 해결하기 위해서는 뭔가 더 추가해주어야 한다!!

2. 해싱관련 코드 추가

from rest_framework import serializers
from user.models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"
        
    def create(self, validated_data):
        user = super().create(validated_data)
        password = user.password
        user.set_password(password)
        user.save()
        return user


이렇게 작성하면 비밀번호 해싱이 되어서 로그인이 잘 된다!!!

8. jwt 페이로드 커스터마이징 해보기

PayLoad 부분에 email이 나오게 커스터마이징을 해보자!!
페이로드 커스터마이징 공식문서 : https://django-rest-framework-simplejwt.readthedocs.io/en/latest/customizing_token_claims.html

- urls.py

from django.urls import path, include
from user import views
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('signup/', views.UserView.as_view(), name='user_view'),
    path('api/token/', views.CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

2번째 path views.CustomTokenObtainPairView.as_view()로 수정

- view.py

from rest_framework.views import APIView
from rest_framework import status
from rest_framework.response import Response
from user.serializers import CustomTokenObtainPairSerializer, UserSerializer
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
)

class UserView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({"message":"가입완료!"}, status=status.HTTP_201_CREATED)
        else:
            return Response({"message":f"${serializer.errors}"}, status=status.HTTP_400_BAD_REQUEST)
        
class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer

class CustomTokenObtainPairView 추가

- serializers.py

from rest_framework import serializers
from user.models import User
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"
        
    def create(self, validated_data):
        user = super().create(validated_data)
        password = user.password
        user.set_password(password)
        user.save()
        return user
    

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)

        token['email'] = user.email

        return token

class CustomTokenObtainPairSerializer 추가

이렇게 하면 PayLoad에 email이 추가된다!!

9. 토큰주기 설정과 drf에서 권한설정

유저 settings.py 관련 자료 : https://django-rest-framework-simplejwt.readthedocs.io/en/latest/settings.html

- 로그인 시간 늘리기

settings.py에 아래 내용 추가

from datetime import timedelta

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=720),}

로그인 시간이 720분으로 변경되었다!!

- 로그인이 되어있는지 확인

- urls.py

from django.urls import path, include
from user import views
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('signup/', views.UserView.as_view(), name='user_view'),
    path('mock/', views.mockView.as_view(), name='mock_view'),
    path('api/token/', views.CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

mock 관련 url 추가!

- views.py

from rest_framework.views import APIView
from rest_framework import status
from rest_framework.response import Response
from rest_framework import permissions
from user.serializers import CustomTokenObtainPairSerializer, UserSerializer
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
)

class UserView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({"message":"가입완료!"}, status=status.HTTP_201_CREATED)
        else:
            return Response({"message":f"${serializer.errors}"}, status=status.HTTP_400_BAD_REQUEST)
        
class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer
    
class mockView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    def get(self, request):
        return Response("get 요청")

class mockView 추가&관련 import 추가

- 포스트맨으로 확인


1. header로 들어가기
2. key값은 Authorization, value값은 Bearer +access token 작성
Bearer작성하고 한칸 띄고 access toekn 작성해야 한다!
3. send
4. 잘 로그인 되었다는 "get 요청"이 뜬다!!

10. refreshtoken으로 access token 받기


1. 주소를 http://127.0.0.1:8000/user/api/token/refresh/ 로 변경
2. login으로 가서 로그인 다시하고 refresh token 복사해오기
3. 사진처럼 붙여넣고 send
4. 결과값으로 access token이 나온다!

11. 프론트엔드 예시

js에서 버튼이 눌려지고 있는지 항상 꼭꼭 확인하기!!!
한줄 한줄 잘 실행되고 있는지 확인해가면서 개발하자!!
안그러면 나중에 오류가 날 때 어디서 안되는건지 알 수가 없다..
자바스크립트는 친절하게 어디서 오류가 나는지 알려주지 않기 때문에...

1. html 파일의 email과 password를 자바스크립트 파일에서 읽을 수 있게 하기(회원가입)

화살표 함수 관련 자료 : https://poiemaweb.com/es6-arrow-function
getElementById 관련 자료 : https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
자바스크립트 변수인 let, const, var의 차이 관련 자료: https://www.howdy-mj.me/javascript/var-let-const

- signup.html

<!DOCTYPE html>
<html lang="en">
<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</title>
    <script src="api.js"></script>
</head>
<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="handleSignin()">제출</button>
    </form>
</body>
</html>

- api.js

window.onload = ()=>{
    console.log("로딩완료")
}

function handleSignin(){
    const email = document.getElementById("email").value
    const password = document.getElementById("password").value
    console.log(email, password)
}

2. fetch api를 사용해 백엔드로 전송하기(회원가입)

fetch 관련 자료 : https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch

- api.js

window.onload = ()=>{
    console.log("로딩완료")
}

async function handleSignin(){
    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/user/signup/', {
        headers:{
            'content-type':'application/json',
        },
        method:'POST',
        body:JSON.stringify({
            "email":email,
            "password":password
        })
    })

    console.log(response)
}

같은 도메인에서 요청을 보낼때는 허용이 되어있는데 다른 도메인에서 요청을 보낼 때는 보안상의 문제로 별도의 허용이 필요하다. 이 때 CORS로 허용해주면 된다.
CORS 관련 자료 : https://github.com/adamchainz/django-cors-headers

- 회원가입 결과

3. 로그인

- login.html

<!DOCTYPE html>
<html lang="en">
<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</title>
    <script src="api.js"></script>
</head>
<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>
</body>
</html>

- api.js

window.onload = ()=>{
    console.log("로딩완료")
}

async function handleLogin(){
    const email = document.getElementById("email").value
    const password = document.getElementById("password").value
    
    const response = await fetch('http://127.0.0.1:8000/user/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)
}

여기까지 하면 로그인이 되는것까지 확인할 수 있다.

하지만 아직 access token이 로컬스토리지에 저장되지 않은상태이다!
토큰을 로컬스토리지에 저장해보자!!

4. 로그인 access, refresh 토큰 로컬스토리지에 저장하기

- api.js

window.onload = ()=>{
    console.log("로딩완료")
}

async function handleLogin(){
    const email = document.getElementById("email").value
    const password = document.getElementById("password").value
    
    const response = await fetch('http://127.0.0.1:8000/user/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);
}

아래의 코드를 기존 코드에 추가하면 된다!!

localStorage.setItem("access", response_json.access);
localStorage.setItem("refresh", response_json.refresh);

5. 페이로드 값들을 로컬스토리에 저장하기

- api.js

window.onload = ()=>{
    console.log("로딩완료")
}

async function handleSignin(){
    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/user/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
    
    const response = await fetch('http://127.0.0.1:8000/user/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);
}

제일 아래쪽에 const base64Url부터 끝까지의 내용을 추가!

6. 메인화면에 이메일 띄우기

- index.html

<!DOCTYPE html>
<html lang="en">
<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>홈페이지</title>
    <script src="index.js"></script>
</head>
<body>
    <h1>홈페이지</h1>
    <div id="intro"></div>
</body>
</html>

- index.js

console.log("로딩되었습니다!")


window.onload = ()=>{
    const payload = localStorage.getItem("payload");
    const payload_parse = JSON.parse(payload)
    console.log(payload_parse.email)

    const intro = document.getElementById("intro")
    intro.innerText = payload_parse.email
}

7. 로그인 되어있는지 확인(로그인 검증)

- login.html

<!DOCTYPE html>
<html lang="en">
<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</title>
    <script src="api.js"></script>
</head>
<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>
</body>
</html>

- api.js

window.onload = ()=>{
    console.log("로딩완료")
}

async function handleSignin(){
    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/user/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
    
    const response = await fetch('http://127.0.0.1:8000/user/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);
}

async function handleMock(){
    const response = await fetch('http://127.0.0.1:8000/user/mock/', {
        headers:{
            "Authorization":"Bearer " + localStorage.getItem("access")
        },
        method:'GET',
    })

    console.log(response)
}

- 로그인 안됐을 때

- 로그인 됐을 때

  1. 로그아웃
    로컬스토리지에 저장된 페이로드, 엑세스토큰, 리프레시토큰을 지원주면 된다!

- login.html

<!DOCTYPE html>
<html lang="en">
<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</title>
    <script src="api.js"></script>
</head>
<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>
</html>

- api.js

window.onload = ()=>{
    console.log("로딩완료")
}

async function handleSignin(){
    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/user/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
    
    const response = await fetch('http://127.0.0.1:8000/user/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);
}

async function handleMock(){
    const response = await fetch('http://127.0.0.1:8000/user/mock/', {
        headers:{
            "Authorization":"Bearer " + localStorage.getItem("access")
        },
        method:'GET',
    })

    console.log(response)
}

function handleLogout(){
    localStorage.removeItem("access")
    localStorage.removeItem("refresh")
    localStorage.removeItem("payload")
}
profile
개발과 지식의 성장을 즐기는 개발자

0개의 댓글