DRF 权限类 IsAuthenticated 不适用于 React js JWT 身份验证

时间:2021-02-02 13:32:56

标签: reactjs django django-rest-framework django-rest-framework-simplejwt

我使用 React 和 Django REST 创建了一个身份验证应用程序。创建帐户和登录时它工作正常。但是当我想在使用 IsAuthenticated 权限类登录后查看某些内容时它不起作用。它将错误显示为图像。as same as the image。未经许可,它可以正常工作。 REST 权限和 JWT 设置:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],

}

# jwt permission
SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=14),
    'ROTATE_REFRESH_TOKENS': True,
    'BLACKLIST_AFTER_ROTATION': True,
    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUTH_HEADERS_TYPES': ('JWT',),
    'USER_ID_FIELDS': 'id',
    'USER_ID_CLAIM': 'user_id',
    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',
}

和 React 代码: 主页视图

import React, { Component } from "react"
import axiosInstance from "../AxiosApi"

export default class Home extends Component {
    constructor() {
        super()
        this.state = {
            aboutData: []
        }
    }
    getData = async () => {
        try {
            const response = await axiosInstance.get("/v1/about/")
            this.setState({
                aboutData: response.data
            })
            return response.data
        } catch (error) {
            console.log("Error: ", JSON.stringify(error, null, 4))
            throw error
        }
    }

    componentDidMount() {
        const data = this.getData()
        console.log(data)
    }
    render() {
        return (
            <div>
                {this.state.aboutData.map((item) => (
                    <div key={item.id}>
                        <h2>Name: {item.name}</h2>
                        <p>Address: {item.address}</p>
                        <p>Phone Number: {item.phone_no}</p>
                        <br></br>
                    </div>
                ))}
            </div>
        )
    }
}

AxiosInstance

import axios from "axios"

const baseURL = "http://127.0.0.1:8000/api/"

const axiosInstance = axios.create({
    baseURL: baseURL,
    timeout: 5000,
    headers: {
        Authorization: localStorage.getItem("access_token")
            ? "JWT " + localStorage.getItem("access_token")
            : null,
        "Content-Type": "application/json",
        accept: "application/json"
    }
})

axiosInstance.interceptors.response.use(
    (response) => response,
    (error) => {
        const originalRequest = error.config

        // Prevent infinite loops early
        if (
            error.response.status === 401 &&
            originalRequest.url === baseURL + "token/refresh/"
        ) {
            window.location.href = "/login/"
            return Promise.reject(error)
        }

        if (
            error.response.data.code === "token_not_valid" &&
            error.response.status === 401 &&
            error.response.statusText === "Unauthorized"
        ) {
            const refreshToken = localStorage.getItem("refresh_token")

            if (refreshToken) {
                const tokenParts = JSON.parse(atob(refreshToken.split(".")[1]))

                // exp date in token is expressed in seconds, while now() returns milliseconds:
                const now = Math.ceil(Date.now() / 1000)
                console.log(tokenParts.exp)

                if (tokenParts.exp > now) {
                    return axiosInstance
                        .post("/token/refresh/", { refresh: refreshToken })
                        .then((response) => {
                            localStorage.setItem(
                                "access_token",
                                response.data.access
                            )
                            localStorage.setItem(
                                "refresh_token",
                                response.data.refresh
                            )

                            axiosInstance.defaults.headers["Authorization"] =
                                "JWT " + response.data.access
                            originalRequest.headers["Authorization"] =
                                "JWT " + response.data.access

                            return axiosInstance(originalRequest)
                        })
                        .catch((err) => {
                            console.log(err)
                        })
                } else {
                    console.log("Refresh token is expired", tokenParts.exp, now)
                    window.location.href = "/login/"
                }
            } else {
                console.log("Refresh token not available.")
                window.location.href = "/login/"
            }
        }

        // specific error handling done elsewhere
        return Promise.reject(error)
    }
)

export default axiosInstance

0 个答案:

没有答案