0

I have a web app on Django with simple authentication as follows:

# in a request handler
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
    login(request, user)
    return redirect('/')

The app works fine running on localhost and on real servers through HTTPS at my-app.com (no a real domain of course). Now I'm trying to make it running on Kubernetes and Minikube. I've set up a Deployment, Service, NginX-Ingress, also I specified minikube ip in my /etc/hosts file as my-app.local, and I can access it using Chrome browser, but the authentication doesn't work! Browser saves no cookies, and I always get redirected to the log in page.

And I cannot find any reason: I've checked server logs and browser network traces, they look fine, I also used curl to compare authentication method results of real .com version of the app and my minikube/.local version, they are pretty same, I see correct Set-Cookie: ... everywhere, but the cookies don't get saved in the browser. What can be the cause of this problem??

Update

I've changed my local domain to test.my-app.com, but got no improvements :(

Update 2

I turned off the Ingress, so it's not related to the problem.

In addition, I have added middleware to my Django app to log cookies of each request, and I also made a script to check what's happening:

with requests.Session() as session:
    response = session.post(url, data={
        'username': 'some-login',
        'password': 'some-password',
    })
    response = session.get(url)
    print(response.content.decode('utf-8'))
    print(session.cookies)

When the url is set to the real app or Django app on my localhost, I get cookies csrftoken and sessionid, and the response is showing the user's personal page. I also see the cookies in the server logs

When the url is set to the Docker/K8s/Minikube service, I get the same cookies in the script, BUT the response shows log in page again. Also, the server logs show no cookies... Looks like something related to Django cookies processing.

AivanF.
  • 1,134
  • 2
  • 23
  • 52
  • Try changing the TLD from `.local` to `.test` or `.lan`. See the [possible cause](https://stackoverflow.com/a/347997). –  Oct 19 '20 at 18:09
  • @Melvyn hi and thanks for your reply! I changed TLD to `.test` but got no difference `:(` I guess the topic that you linked is about `127.0.0.1` / `localhost` only, not about such domains... – AivanF. Oct 19 '20 at 18:33
  • Yep, worth a shot. I stay away from .local, cause it's reserved for ["dynamic devices" (multicast DNS / Zeroconf)](https://en.wikipedia.org/wiki/.local). Then the next thing is timestamps. Make sure the cookie time makes sense. And then you're pretty much out of options assuming code is identical. –  Oct 19 '20 at 20:27
  • @Melvyn tanks for the advice! I just looked at timestamps, and yes, they're correct... But maybe NginX-Ingress proxy eats the cookies before resending requests to the pod with Django so that cookies get reset? – AivanF. Oct 19 '20 at 21:39
  • Then the request would send them. The first page after authentication should have raw request headers with Cookie: in them. And in the view or middleware you can log `request.COOKIES` to confirm they haven't arrived. –  Oct 19 '20 at 21:43

1 Answers1

0

I checked all the settings of Django app and found out that the SESSION_COOKIE_SECURE option was the cause of the problem, as the doc says:

If this is set to True, the cookie will be marked as “secure”, which means browsers may ensure that the cookie is only sent under an HTTPS connection.

The app is configured to use this and some other settings for security reasons when running in prod mode, and my K8s configuration was not configured to run in debug mode.

AivanF.
  • 1,134
  • 2
  • 23
  • 52