What I want to accomplish is a secure and user experience friendly approach to authenticating and storing user's token.
As seen here the recommended answer suggests to use a set of two cookies which would have to have the secure and httpOnly attributes (Since I have Django and React on different domains I would not be able to use any sort of sameSite cookie)
In the same question the next best answer proposes using Redux (Is Redux even more secure?) to store the token in a variable and refresh it with a refresh token stored in LocalStorage that would be used to get a auth token. Now the problem I see with this is that he mentions that he used LocalStorage in his solution as a cookie would not be good for his stateless approach. If I am not mistaken a cookie is neither stateful nor stateless as is just a transport medium and what is inside is what is stateless or not such as a sessionId which Django does with its templates and Session Authentication.
I have seen others recommend using an httpOnly cookie and a csrf token which is the approach I wanted to take. I want to have users authenticate and if user is found then a token is returned in a httpOnly cookie and a csrf token that can be accessible by js to prevent attacks. This would help mitigate both issues I am concerned about. Additionally, I would have to implement a refresh token as each time the page is refreshed the cookies are lost and I do not want users to have to log in every time they refresh. This is also what I think occurs in pages like SO or Instagram that have tokens in cookies and LocalStorage so there must be something good about it.
With this in mind and my goal mentioned I would like to know the best approach from a security standpoint and how could I accomplish this. I do not want the code to the answer as I am learning how to build my first application which might be used in real world and I security is important. As mentioned in the answer from point 2 despite my limited knowledge I do not see tutorials that just use LocalStorage and do not give it too much thought as helpful except for a quick app.
As of now this is how my API looks using Knox
class LoginViewAPI(generics.GenericAPIView):
authentication_classes = [TokenAuthentication]
permission_classes = [AllowAny]
serializer_class = LoginSerializer
@method_decorator(ensure_csrf_cookie)
def post(self, request):
serializer = LoginSerializer(data = request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data
response=None
if(user is None):
return Response({"message":"The user was not found"}, status=status.HTTP_404_NOT_FOUND)
else:
response=Response({"user": userSerializer(user, context=self.get_serializer_context()).data})
token = AuthToken.objects.create(user)[1]
response.set_cookie(
'auth_token', token,
httponly=True,
)
return response
I still have the to figure out the csrf token part as the decorator does not seem to do its job.