'Django, JWT, React redirect to different page base on different group after log in
I have 2 roles which are member and staff, and i want to redirect to the different pages depend on the users' roles using username and password e.g. after logging in as a member would redirect to member page and as a staff would redirect to onlystaff page. How I can do it. I'm using React Django JWT and Material UI.
the code:
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.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/';
}
}
return Promise.reject(error);
}
);
export default axiosInstance;
Log-in.js
export default function LogIn() {
let history = useHistory();
const initialFormData = Object.freeze({
username: '',
password: '',
});
const [formData, updateFormData] = useState(initialFormData);
const handleChange = (e) => {
updateFormData({
...formData,
[e.target.name]: e.target.value.trim(),
});
};
const handleSubmit = (e) => {
e.preventDefault();
console.log(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={handleChange}/>
<TextField
margin="normal"
required
name="password"
label="password"
type="password"
id="password"
autoComplete="current-password"
onChange={handleChange}/>
<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'),
]
Solution 1:[1]
in your TokenObtainPairView.as_view() add the role of the user or the redirectPath based on the role, into the response. Then inside your handleSubmit add this:
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
Edit
You can edit the JWT itself in django, and read it from the token in the frontend, as per this
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
