この記事はメモようなので詳しい説明はありません。

https://github.com/yuki5155/jwtdjango

必要なライブラリをインストールする

pipenv install djangorestframework
pipenv install djangorestframework-simplejwt
pipenv install django-cors-headers

Django側の設定をする

ミドルウェアのところを設定しないとエラーが出るか動作しない

settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'jwtauth',
    'corsheaders',
    'rest_framework',
]

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        #Simple JWTを読み込む
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        #'rest_framework.authentication.TokenAuthentication',

    ),  
}



SIMPLE_JWT = {
    #トークンの時間を5ふんに設定する
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=14),
    'ROTATE_REFRESH_TOKENS': True,
    'BLACKLIST_AFTER_ROTATION': False,
    #暗号のアルゴリズム設定
    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUTH_HEADER_TYPES': ('JWT',),
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',
    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',
}


CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'corsheaders.middleware.CorsMiddleware',
]

models.py
from django.db import models

class Todo(models.Model):
    title = models.CharField(max_length=90)
views.py
from .serializers import MyTokenObtainPairSerializer,TodoSerializers
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import Todo
from rest_framework.permissions import AllowAny, IsAuthenticated
# Create your views here.
class ObtainTokenPairWithColorView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

class TodoView(APIView):
    permission_classes = [AllowAny]

    def get(self, request):
        todo = Todo.objects.all()
        serializer = TodoSerializers(todo, many=True, context={"request": request})
        return Response(serializer.data)

    def post(self, request):
        serializer = TodoSerializers(data=request.data)

        if serializer.is_valid():
            serializer.save()

        todo = Todo.objects.all()

        serializer = TodoSerializers(todo, many=True, context={"request": request})
        return Response(serializer.data)

serualizers.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers
from .models import Todo


#トークンを発行するためのクラス
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):

    @classmethod
    def get_token(cls, user):
        token = super(MyTokenObtainPairSerializer, cls).get_token(user)

        # Add custom claims
        return token
class TodoSerializers(serializers.ModelSerializer):

    class Meta:
        model = Todo

        fields = ['title',]

 python manage.py createsuperuser

トークンのは発行を試すために下記にアクセス

http://localhost:8000/token/obtain/

ユーザー名とパスワードを入力してアクセストークンとリフレッシュトークンが表示されたらOK

React側の処理

App.js
import logo from './logo.svg';
import './App.css';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Home from './Home';
import Login from './Login';

function App() {
  return (
    <div className="App">
      <header>

      </header>
      <Router>
          <Route exact path='/' component={Home}/>
          <Route exact path='/login' component={Login}/>

      </Router>

    </div>
  );
}

export default App;


Home.jsに認証なしでアクセスをすると認証ページのlogin.jsに飛ばされる

Home.js
import React, { useState, useEffect, useRef } from 'react';
import axios from 'axios';
import {useCookies } from 'react-cookie';
import  { useHistory } from 'react-router-dom';


function Home() {
    const [cookies, setCookie] = useCookies(['auth']);
    const apiUrl = 'http://localhost:8000'
    const token = cookies.accesstoken;
    const history = useHistory();

    useEffect(() => {
        axios.get(`${apiUrl}`,{

          headers: {
              'Content-Type': 'application/json',
              "authorization": `JWT ${token}`,


          }
        },
        )

          .then(

            response =>{



            },

            error =>{

              if(error.response.status === 401){
                console.log('401エラーです');
                history.push('/login');
              }
            }
          )

      }, [])






    return (

        <>
            <p>sggassss</p>





        </>




    );
  }

  export default Home;


アクセストークンをcookieに保存をする

エラーは起きなかった場合はHome.jsに飛ばされる

Login.js
import React, { useState, useEffect, useRef } from 'react';
import { useCookies } from 'react-cookie';
import axios from 'axios';
import { useForm } from "react-hook-form";
import  { useHistory } from 'react-router-dom';


function Login() {
    const apiUrl = 'http://localhost:8000'
    const history = useHistory();

    const [cookies, setCookie] = useCookies();
    const { register, handleSubmit, watch, errors } = useForm();

    const getJwt = async (data) =>{
        console.log(data)
        await axios.post(`${apiUrl}/token/obtain/`,
        {


          username:data.userid,
          password:data.password,


        },


        )
        .then(function (response) {

            console.log(response.data.access)



          setCookie('accesstoken', response.data.access, { path: '/' });
          setCookie('refreshtoken', response.data.refresh, { path: '/' });

          history.push('/');



        })


      };






    return (

        <>
            <p>sggassss</p>

            <form onSubmit={handleSubmit(getJwt)}>
            <input className='form-control' name="userid" ref={register} />
            <input className='form-control' name="password" type="password" ref={register({ required: true })} />
            <input className='btn btn-secondary' type="submit" value="ログイン" />

            </form>





        </>




    );
  }

  export default Login;