使用JWT身份验证向DRF发送axios请求失败

时间:2020-04-22 21:29:47

标签: javascript reactjs django-rest-framework axios

我有一个带有JWT auth的Django rest API,用于使用react构建的注册和登录。 尝试登录用户时,出现403禁止错误。

我在请求的标题中添加了csrf令牌,使用控制台时,我可以在promise中看到它,所以这不是问题。

我只是不明白这篇文章在哪里

import axios from "axios";
import Cookies from "js-cookie";

var csrftoken = Cookies.get("csrftoken");

const axiosInstance = axios.create({
  baseURL: "http://127.0.0.1:8000/api/",
  timeout: 5000,
  headers: {
    HTTP_X_CSRF_TOKEN: csrftoken,
    Authorization: localStorage.getItem("access_token")
      ? "JWT " + localStorage.getItem("access_token")
      : null,
    "Content-Type": "application/json",
    accept: "application/json",
    withCredentials: true,
  },
});

axiosInstance.interceptors.response.use(
  (response) => response,
  (error) => {
    const originalRequest = error.config;
    // test for token presence, no point in sending a request if token isn't present
    if (
      localStorage.getItem("refresh_token") &&
      error.response.status === 401 &&
      error.response.statusText === "Unauthorized"
    ) {
      const refresh_token = localStorage.getItem("refresh_token");

      return axiosInstance
        .post("/token/refresh/", { refresh: refresh_token })
        .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);
        });
    }
    // specific error handling done elsewhere
    return Promise.reject({ ...error });
  }
);

export default axiosInstance;

使用axios实例的登录组件:

import React, { Component } from "react";
import axiosInstance from "../axiosApi";
import DjangoCSRFToken from "django-react-csrftoken";

class Login extends Component {
  constructor(props) {
    super(props);
    this.state = { username: "", password: "" };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({ [event.target.name]: event.target.value });
  }

  async handleSubmit(event) {
    event.preventDefault();
    try {
      const response = await axiosInstance.post("/token/obtain/", {
        username: this.state.username,
        password: this.state.password,
      });
      axiosInstance.defaults.headers["Authorization"] =
        "JWT " + response.data.access;
      localStorage.setItem("access_token", response.data.access);
      localStorage.setItem("refresh_token", response.data.refresh);
      return response;
    } catch (error) {
      throw error;
    }
  }

  render() {
    return (
      <div>
        Login
        <form onSubmit={this.handleSubmit}>
          <DjangoCSRFToken />
          <label>
            Username:
            <input
              name="username"
              type="text"
              value={this.state.username}
              onChange={this.handleChange}
            />
          </label>
          <label>
            Password:
            <input
              name="password"
              type="password"
              value={this.state.password}
              onChange={this.handleChange}
            />
          </label>
          <input type="submit" value="Submit" />
        </form>
      </div>
    );
  }
}
export default Login;

点击提交时的控制台:

console output of the login page

1 个答案:

答案 0 :(得分:0)

请尝试从通话中删除CSRF。并使用@csrf_exepmt获取更多信息,请点击此链接。 Django csrf_exempt使用您的JWT就足够了。

示例:

@csrf_exempt
def myEndpoint():
  // my code