react admin returns CRUD 操作时出现未经授权的 401 错误
react admin returns Unauthorized 401 error upon CRUD operations
我正在做一个 react-admin 项目。后端是使用运行在 docker 容器上的 Django rest 框架编写的。访问和刷新令牌的身份验证端点使用 djangorestframework-simplejwt
编写,并分别在 http://localhost:8000/api/token/
和 http://localhost:8000/api/token/refresh/
提供服务。
我已经为 React 管理员编写了自己的 authProvider.js
和 dataProvider.js
。 authProvider.js
的 login
和 checkAuth
函数看起来像这样
// in src/authProvider.js
import jwt from "jsonwebtoken";
export default {
login: async ({ username, password }) => {
const request = new Request('http://localhost:8000/api/token/', {
method: 'POST',
body: JSON.stringify({ username, password }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
const response = await fetch(request);
if (response.status < 200 || response.status >= 300) {
throw new Error(response.statusText);
}
const { refresh, access } = await response.json();
localStorage.setItem('refreshToken', refresh);
localStorage.setItem('accessToken', access);
},
logout: ...
checkAuth: async () => {
const accessToken = localStorage.getItem('accessToken');
const refreshToken = localStorage.getItem('refreshToken');
if (accessToken && refreshToken) {
const { exp } = await jwt.decode(accessToken);
if (exp > (new Date().getTime() / 1000) - 10) {
return Promise.resolve();
} else {
const request = new Request('http://localhost:8000/api/token/refresh/', {
method: 'POST',
body: JSON.stringify({ "refresh": refreshToken }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
const response = await fetch(request)
.then(response => {
if (response.status !== 200) {
throw new Error(response.statusText);
}
return response.json();
})
.then(({ token }) => {
localStorage.setItem('accessToken', token);
return Promise.resolve();
});
return response;
}
}
return Promise.reject();
},
checkError: ...
getPermissions: () => Promise.resolve(),
}
检索数据工作正常。但是每当我执行创建、编辑和删除操作时,我都会自动注销并出现 401 未授权错误。来自 docker 服务器日志的错误消息
Unauthorized: /api/products/2
"PUT /api/products/2 HTTP/1.1" 401
来自浏览器控制台的错误:PUT HTTP://localhost:8000/api/products/2 401 (Unauthorized)
在添加 authProvider
并使用 docker 容器作为后端之前,CRUD 数据突变工作正常,使用本地 python venv 作为后端。所以我假设 dataProvider.js
在这里不负责任。
我已经有一段时间没弄明白了。谁能帮我弄清楚我在这里可能做错了什么?谢谢你的时间。
编辑 1:似乎访问令牌在 API 请求期间未从前端发送,因此服务器返回 401 Unauthorized
您需要修改 dataProvider
以包含令牌(在令牌、cookie 或 GET 参数中,具体取决于您的后端要求)。这在 the react-admin auth documentation:
中有解释
import { fetchUtils, Admin, Resource } from 'react-admin';
import simpleRestProvider from 'ra-data-simple-rest';
const httpClient = (url, options = {}) => {
if (!options.headers) {
options.headers = new Headers({ Accept: 'application/json' });
}
const { token } = JSON.parse(localStorage.getItem('auth'));
options.headers.set('Authorization', `Bearer ${token}`);
return fetchUtils.fetchJson(url, options);
};
const dataProvider = simpleRestProvider('http://localhost:3000', httpClient);
const App = () => (
<Admin dataProvider={dataProvider} authProvider={authProvider}>
...
</Admin>
);
我正在做一个 react-admin 项目。后端是使用运行在 docker 容器上的 Django rest 框架编写的。访问和刷新令牌的身份验证端点使用 djangorestframework-simplejwt
编写,并分别在 http://localhost:8000/api/token/
和 http://localhost:8000/api/token/refresh/
提供服务。
我已经为 React 管理员编写了自己的 authProvider.js
和 dataProvider.js
。 authProvider.js
的 login
和 checkAuth
函数看起来像这样
// in src/authProvider.js
import jwt from "jsonwebtoken";
export default {
login: async ({ username, password }) => {
const request = new Request('http://localhost:8000/api/token/', {
method: 'POST',
body: JSON.stringify({ username, password }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
const response = await fetch(request);
if (response.status < 200 || response.status >= 300) {
throw new Error(response.statusText);
}
const { refresh, access } = await response.json();
localStorage.setItem('refreshToken', refresh);
localStorage.setItem('accessToken', access);
},
logout: ...
checkAuth: async () => {
const accessToken = localStorage.getItem('accessToken');
const refreshToken = localStorage.getItem('refreshToken');
if (accessToken && refreshToken) {
const { exp } = await jwt.decode(accessToken);
if (exp > (new Date().getTime() / 1000) - 10) {
return Promise.resolve();
} else {
const request = new Request('http://localhost:8000/api/token/refresh/', {
method: 'POST',
body: JSON.stringify({ "refresh": refreshToken }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
const response = await fetch(request)
.then(response => {
if (response.status !== 200) {
throw new Error(response.statusText);
}
return response.json();
})
.then(({ token }) => {
localStorage.setItem('accessToken', token);
return Promise.resolve();
});
return response;
}
}
return Promise.reject();
},
checkError: ...
getPermissions: () => Promise.resolve(),
}
检索数据工作正常。但是每当我执行创建、编辑和删除操作时,我都会自动注销并出现 401 未授权错误。来自 docker 服务器日志的错误消息
Unauthorized: /api/products/2
"PUT /api/products/2 HTTP/1.1" 401
来自浏览器控制台的错误:PUT HTTP://localhost:8000/api/products/2 401 (Unauthorized)
在添加 authProvider
并使用 docker 容器作为后端之前,CRUD 数据突变工作正常,使用本地 python venv 作为后端。所以我假设 dataProvider.js
在这里不负责任。
我已经有一段时间没弄明白了。谁能帮我弄清楚我在这里可能做错了什么?谢谢你的时间。
编辑 1:似乎访问令牌在 API 请求期间未从前端发送,因此服务器返回 401 Unauthorized
您需要修改 dataProvider
以包含令牌(在令牌、cookie 或 GET 参数中,具体取决于您的后端要求)。这在 the react-admin auth documentation:
import { fetchUtils, Admin, Resource } from 'react-admin';
import simpleRestProvider from 'ra-data-simple-rest';
const httpClient = (url, options = {}) => {
if (!options.headers) {
options.headers = new Headers({ Accept: 'application/json' });
}
const { token } = JSON.parse(localStorage.getItem('auth'));
options.headers.set('Authorization', `Bearer ${token}`);
return fetchUtils.fetchJson(url, options);
};
const dataProvider = simpleRestProvider('http://localhost:3000', httpClient);
const App = () => (
<Admin dataProvider={dataProvider} authProvider={authProvider}>
...
</Admin>
);