How do I properly implement DRF TokenAuthentication without the request object returning an anonymous user when I try to log in?
according to the docs, when authenticated, the TokenAuthentication
object provides the request.user
which is the Django user instance and the request.auth
which is the token instance. But even after authentication, request.user
returns anonymouse user.
What could I be doing wrong?
Client request:
//function to get token
export default function axiosConfig() {
// request header
const headers = {
"Content-Type": "application/json"
}
// Get token from local storage. Token is stored when user registers.
const token = localStorage.getItem("token");
if (token) headers["Authorisation"] = `Token ${token}`;
return headers;
}
Redux action
import axiosConfig from "../../utils/axiosConfig";
const config = axiosConfig
export const login = (email, password) => (dispatch, getState) => {
const body = { email, password };
// Change to absoulte path when deploying to production
axios
.post("http://localhost:8000/api/auth/login", body, config())
.then((res) => {
dispatch({
type: SIGN_IN_SUCCESFUL,
payload: res.data,
});
console.log(res);
})
.catch((err) => {
dispatch({
type: SIGN_IN_FAIL,
payload: err.response,
});
console.log(err.response.data, err.response.status);
});
};
Django
url:
from django.urls import path
from authentication.views import RegisterationView
from authentication.views import LoginView
from authentication.views import LogoutView
urlpatterns = [
path("auth/register", RegisterationView.as_view()),
path("auth/login", LoginView.as_view()),
path("auth/logout/<int:id>", LogoutView.as_view()),
]
Serializer:
The LoginResponseSerializer
is used to provide response data to the client
class LoginSerializer(serializers.Serializer):
"""Login serializer"""
username = serializers.CharField()
password = serializers.CharField(required=True)
class LoginResponseSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [
"id",
"username",
"first_name",
"last_name",
"email",
"is_active",
"is_staff",
]
read_only_fields = ["id", "is_active", "is_staff"]
View:
class LoginView(APIView):
"""Login View"""
permision_classs = [permissions.AllowAny]
def post(self, request):
serializer = LoginSerializer(data=request.data)
if serializer.is_valid():
print(serializer.data) # Data is present
user = authenticate(request, **serializer.data) # Valid credentials. User object is returned.
response_serializer = LoginResponseSerializer(user)
if user is not None and login(request, user):
print(request.user) # User is anonymous
token, created_token = Token.objects.get_or_create(user_id=user.id)
if isinstance(created_token, Token):
token = created_token
return Response(
{
"user": response_serializer.data,
"status": {
"message": "user authenticated",
"code": status.HTTP_200_OK,
},
"token": token.key,
}
)
raise serializers.ValidationError(
"Invalid Username or Password. Please try again"
)
return Response(
{"error": serializer.errors, "status": status.HTTP_403_FORBIDDEN}
)