我有一个带有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;
点击提交时的控制台:
答案 0 :(得分:0)
请尝试从通话中删除CSRF。并使用@csrf_exepmt获取更多信息,请点击此链接。 Django csrf_exempt使用您的JWT就足够了。
示例:
@csrf_exempt
def myEndpoint():
// my code