This is my first app in Django + React so I am not professional. I am writing view-set and trying to get the current user from the request but I got anonymous user even though the user is logged in. My frontend is in React and I am using django-allauth and django-rest-auth authentication.
I was trying to find out if there is an issue with token but it seems that works fine that. I have also CustomUser so maybe is that...
Here is my login function in React and Redux:
export const authLogin = (username, password) => {
return dispatch => {
dispatch(authStart());
axios.post('http://localhost:8000/rest-auth/login/', {
username: username,
password: password
},)
.then(res => {
const token = res.data.key;
const user = username;
const expirationDate = new Date(new Date().getTime() + 3600 * 1000);
localStorage.setItem('token', token);
localStorage.setItem('user', user);
localStorage.setItem('expirationDate', expirationDate);
dispatch(authSuccess(token));
dispatch(checkAuthTimeout(3600));
})
.catch(err => {
dispatch(authFail(err))
})
}
}
const authSuccess = (state, action) => {
return updateObject(state, {
token: action.token,
error: null,
loading: false
});
}
user matches page for the viewset:
import React from "react";
import { Component } from "react";
import { NavLink } from 'react-router-dom';
import axios from 'axios';
class UserMatches extends Component {
state = {
matches: null
}
componentDidMount() {
this.getUserMatches()
}
getUserMatches = () => {
const token = `Token ` + localStorage.getItem('token')
console.log(token)
const headers = {
'Authorization': token
}
axios.get('http://localhost:8000/matches/api/matches/', {"headers": headers})
.then(res => {
console.log(res.data)
this.setState({
matches: res.data
})
})
.catch(err => {
console.log(err)
})
}
render() {
const matches = this.state.matches ?
(
this.state.matches.map((match) => {
const match_link = '/matches/' + match.id + '/'
return (
<div>
<div class="divider"></div>
<div class="section">
<h5><NavLink to={match_link}>{match.name}</NavLink></h5>
<p>Date: {match.match_date}</p>
<p>Time: {match.match_time}</p>
<p>Location: {match.location}</p>
<p>Quantity of players: {match.quantity_of_players}</p>
<p>Created by: {match.creator}</p>
</div>
</div>
)
})
)
:
(
<div className="container center">
<div class="preloader-wrapper small active">
<div class="spinner-layer spinner-green-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
</div>
)
return (
<div className="container">
{matches}
</div>
)
}
}
export default UserMatches;
and here is my viewset and custom user model:
class MatchViewset(viewsets.ViewSetMixin, generics.ListAPIView):
serializer_class = MatchSerializer
def get_queryset(self):
user = self.request.user
print(user)
return Match.objects.filter(creator=user)
class CustomUser(AbstractUser):
GENDER_CHOICES = (
("F", "FAMALE"),
("M", "MALE")
)
username = models.CharField(blank=False, max_length=255, unique=True)
first_name = models.CharField(max_length=255, blank=False, default="superuser")
second_name = models.CharField(max_length=255, blank=False, default="superuser")
email = models.EmailField(blank=False, unique=True)
age = models.IntegerField(blank=False, default=18)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, blank=True, null=True)
country = models.CharField(blank=True, null=True, max_length=255)
city = models.CharField(blank=True, null=True, max_length=255)
positions = models.ManyToManyField(Position, related_name='positions')
favourite_team = models.CharField(max_length=255, blank=True, null=True)
def __str__(self):
return self.username
I also have adapter:
class CustomUserAccountAdapter(DefaultAccountAdapter):
def save_user(self, request, user, form, commit=True):
user = super().save_user(request, user, form, False)
user_field(user, 'first_name', request.data.get('firstName'))
user_field(user, 'second_name', request.data.get('secondName'))
user_field(user, 'age', request.data.get('age'))
user.save()
return user
and the settings:
ACCOUNT_ADAPTER = 'project_football.adapters.CustomUserAccountAdapter'
AUTH_USER_MODEL = 'accounts.CustomUser'
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend"
)
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
}
ACCOUNT_EMAIL_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'username'
ACCOUNT_EMAIL_VERIFICATION = 'none'
As I can see you are using django rest's Token based authentication and you are not passing Token in the HTTP Authorisation header in your match API.When using token based authentication you have to pass token in the HTTP header like this:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
Then your request will pass through DRF's Tokenauthentication class and it will set request.user to a user instance if token received in HTTP header is valid.