Anvil.users.get_user() started returning None

Hi all

I’m using a custom authentication (kind of password-less login) in my “self-hosted” app.
Today, I had to do many changes on the app, such as database location, server side codes, client-side codes etc. Thus I can not diagnose the problem easily.

On the startup page, my call to “anvil.users.force_login” seems to be successful, and I can access the home page. But, when I refresh the page, “anvil.users.get_user()” returns None and due to my code logic, it goes to the custom login page again. Tested on different browsers and users already, with no luck.
I suspect cookies, session ID etc. which I didn’t touch and have very limited knowledge about.
Can anybody suggest a solution or should I share some code maybe?

p.s. app is planned to be used on a LAN and doesn’t include any critical information, so I didn’t use https/SSL, if that means anything.

Here are the questions that come to mind for me:

I thought force_login could only be used server-side. Are you calling it in the startup client code?

Does anvil.users.get_user() return None before you refresh?

1 Like

Yes, force_login is being used at the server side, but called from a custom login form (checking a PIN code sent to user’s email)
Re. 2nd question, here is the code from startup form’s show event:

      res1 = anvil.users.get_user()
      if not res1:
        open_form('login')
      else:
        open_form('pdftools')

After the login form verifies the temporary PIN sent to the user, force_login being called with success, thus “pdftools” form opens.
“pdftools” form also shows some info from users table, using get_user method, which proves that user is logged in.
But when I refresh the browser, it redirects to “login” form due to above code.

On the anvil.server console I can see the following:

[INFO  anvil.app-server.run] [LOG :new-session] {:type browser}

BTW, I can only reproduce this behavior after publishing and git pull from my self-hosted instance, not on the builder. I don’t know a way to refresh that preview at the right side indeed.

Thank you very much for trying to help :+1:

Isn’t there a log-in option that lets the browser remember who was last logged in? Even after a refresh?

1 Like

I have the quite similar issue here:

There are a suggestion how to fix it in the post, but I haven’t implemented yet.

This is another related post as well:

Hopefully, it helps

1 Like

Hi,

When you say ‘started returning None’ does it mean it was working and broke after the updates?

If you are using the standalone server, then:

  • using https/ssl is needed for browser sessions to work as intended. This has to do with specific attributes sent to the browser. Otherwise you will get a new cookie everytime you hit refresh.
  • I never got login between sessions to work where your session is actually kept in the DB and you get another special session token to be valid for configured period. As I really did not need this it was not that important. Possibly the latest version (1.6.6) might fix this but has yet to be published on PyPI.
1 Like

That is the expected behavior actually. For some reason it is broken for me.

Thanks for your help Tony, I will first try to enable SSL (https) on the LAN hostname somehow and see if that helps.

Yes, it was working well before I had cloned the app, made many changes and deployed on a private LAN.
If https is mandatory, there is no need to look for other reasons in my case. I will test with SSL (or maybe deploy this version on web with https just for testing)
Thanks a lot, much appreciated!

That might be the key. My browsers are set to delete cookies and other persistent data on close. Perhaps yours is too?

1 Like

I have managed to create a self-signed certificate on the host, enabled HTTPS and the problem disappeared (although getting browser warnings about invalid certificate).
Thanks to everyone for their inputs.

It’s great @polat, would you mind posting the detailed steps how to create the self-signed certificate and where to put it? I has been struggle with it for a while

Hi Tony,
I tend to use custom solutions all the time, so it may not be super useful for you, but here is the link that helped me a lot.
If you need to use Anvil next to other solutions (i.e. PHP apps), I strongly suggest using Nginx + “Nginx Proxy Manager” It makes everything very simple and manageable.

p.s. I followed the procedure on the same server but as far as I understand, you can generate the certificate on a different machine and move to the actual one.

Thanks so much, I’ll give it a go.

I have the exact same problem, but with an Anvil hosted app (so no https/ssl issue). I never had this problem before.

It seems in my case that it is the editor that can’t handle the remembered login. I get this behavior:

  1. Login via magic-link sent on email. anvil.users.force_login() successfully called on an uplink server.
  2. Use the link to the debug environment directly in the browser: it works - get_user() consistently returns the logged-in user on each reload.
  3. I run the app in the editor. get_user() usually returns None. Sometimes, directly after login, it does return the logged in user. But if I then restart the app once or twice, get_user() will eventually return None.
  4. If after failing in the editor I do step 2 over again, get_user() returns None. It seems like running the app in the editor cleared the remembered login.

I tried to reproduce this with a clean app, but then it worked. For apps I have running in production, the remembered login still works. I tried different browsers, same problem.

Does anybody have an idea about what is going on here?

If it works for new apps, it can be related to the “users” service.
You can remove and re-add the users service from left hand side (right-click).
But I don’t know if it causes other issues or if you lose anything.

20_125409

I tried that, but then I’m not able to add it back in again. When I try, the editor hangs and I have to roll back to an earlier version.

I found the problem. Not surprisingly, the problem was me…

I had made changes when creating users that left the ‘Enabled’ field unchecked. Setting this to True fixed the problem.

What confused me was that I was actually able to log in to a disabled user account, as described in my first reply.

Thanks for your input!

By any chance you can provide a clone app? It seems a very serious issue. Thanks so much

Sure, I have isolated the issue in this app. But I realized that my expectation of a page reload was probably wrong.

https://anvil.works/build#clone:BUYWQOZ34WTLILQU=EWBUOPS3G4VGZ7FH6NFSOYVD

You can also test it out here: https://rotating-hidden-batfish.anvil.app/

I observe this:

When running in the editor:

  • I can force login a disabled (Enabled column in user table = False or None) user.
  • When I restart the app in the editor, it will only remember the logged in user if Enabled=True.

When I run the app directly from a published link or a link to the debug environment:

  • When I close and restart the browser between logins, I get the same behavior as when run in the editor.
  • When I only reload the page between logins, the user is remembered even when Enabled = False or None.

I assumed that a page reload was a clean start for my app, but perhaps a login is supposed to be valid for the full browser session and this is expected behavior?

It makes sense, I guess, as you can then open the app in several tabs without logging in each time.

Can someone confirm that this is how it is supposed to work?

2 Likes