У меня есть 2 роли: член и персонал, и я хочу перенаправить на разные страницы в зависимости от ролей пользователей, используя имя пользователя и пароль, например. после входа в систему в качестве участника будет перенаправлено на страницу участника, а в качестве сотрудника будет перенаправлено на страницу onlystaff. Как я могу это сделать. Я использую React Django JWT и Material UI.
код:
axios.js
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) => {
return response;
},
async function (error) {
const originalRequest = error.config;
if (typeof error.response === 'undefined') {
alert(
'A server/network error occurred. ' +
'Looks like CORS might be the problem. ' +
'Sorry about this - we will get it fixed shortly.'
);
return Promise.reject(error);
}
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]));
const now = Math.ceil(Date.now() / 1000);
console.info(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.info(err);
});
} else {
console.info('Refresh token is expired', tokenParts.exp, now);
window.location.href = '/login/';
}
} else {
console.info('Refresh token not available.');
window.location.href = '/login/';
}
}
return Promise.reject(error);
}
);
export default axiosInstance;
Логин.js
export default function LogIn() {
let history = useHistory();
const initialFormData = Object.freeze({
username: '',
password: '',
});
const [formData, updateFormData] = useState(initialFormData);
const handleChangeEvent = (e) => {
updateFormData({
...formData,
[e.target.name]: e.target.value.trim(),
});
};
const handleSubmit = (e) => {
e.preventDefault();
console.info(formData);
axiosInstance
.post(`token/`, {
username: formData.username,
password: formData.password,
})
.then((res) => {
localStorage.setItem('access_token', res.data.access);
localStorage.setItem('refresh_token', res.data.refresh);
axiosInstance.defaults.headers['Authorization'] =
'JWT ' + localStorage.getItem('access_token');
history.push("/home");
});
};
return (
<Box component = "form" onSubmit = {handleSubmit} noValidate sx = {{ mt: 1, padding: 2 }}>
<TextField
margin = "normal"
required
id = "username"
label = "username"
name = "username"
autoComplete = "username"
autoFocus
onChange = {handleChangeEvent}/>
<TextField
margin = "normal"
required
name = "password"
label = "password"
type = "password"
id = "password"
autoComplete = "current-password"
onChange = {handleChangeEvent}/>
<Button type = "submit" onClick = {handleSubmit}>
LOG IN
</Button>
</Box>
);}
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('core.urls')),
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
в свой TokenObtainPairView.as_view()
добавьте role
пользователя или redirectPath
в зависимости от роли в ответ. Затем внутри вашего handleSubmit
добавьте это:
localStorage.setItem('access_token', res.data.access);
localStorage.setItem('refresh_token', res.data.refresh);
axiosInstance.defaults.headers['Authorization'] =
'JWT ' + localStorage.getItem('access_token');
history.push(res.data.redirectPath); // add this
Вы можете отредактировать сам JWT в django и прочитать его с токена во внешнем интерфейсе, согласно этому
красивый! Я думал, что мой ответ был довольно расплывчатым. Поздравляю с решением — вы вернули роль как часть данных ответа или закодировали ее в JWT?
Я закодировал его, и он работает отлично.
оно работает! Большое спасибо, что поделились.