[Note: I'm keeping the following opening paragraph here for posterity, but this is no longer a session issue - something wrong on the server is preventing CSS from displaying.]
I asked this question on the Wordpress forum, but I seemed to have stumped those folks, so I'll try here. Wordpress clearly handles sessions (in particular, recording that a given browser is logged into a site) differently than PHP in general, and after a server update, I'm having some sort of file permission problem, so I need to find where on the server Wordpress saves files related to its sessions or authentication status. Does anyone know?
The symptoms in my case are two-fold (at least): (1) It always says my session is expired, even right after I log in; (2) There is no styling on the backend - apparently /wp-admin/load-styles.php also requires authentication.
Update: Perhaps symptom #2 is the only symptom. I just discovered that in spite of the "Session expired. Please log in again..." message at the bottom of every page, I can continue to do things without logging in again. Also, at the bottom of the list of themes (which indeed shows three themes) is "No themes found. Try a different search." followed by the "Session expired" bit. So perhaps those things would not be showing if CSS was working, meaning that the problem is only the styles. I disabled all plugins and switched my theme to TwentySixteen, but there was no change in the behavior. I was not using Wordpress when it stopped working - the only thing I did was update my server.
So, if the styles might be the only problem, how do I find out what is preventing /wp-admin/load-styles.php from working?
Update 2: I decided to test Milan's theory that the markup of the "Session expired" would only be produced if something is wrong. On a healthy site, I logged in and then looked at the source code of the dashboard. The following markup is indeed present:
<div id="wp-auth-check"> <button type="button" class="wp-auth-check-close button-link"><span class="screen-reader-text">Close dialog</span></button> <div id="wp-auth-check-form" class="loading" data-src="http://[redacted].com/wp-login.php?interim-login=1"></div> <div class="wp-auth-fallback"> <p><b class="wp-auth-fallback-expired" tabindex="0">Session expired</b></p> <p><a href="http://[redacted].com/wp-login.php" target="_blank">Please log in again.</a> The login page will open in a new window. After logging in you can close it and return to this page.</p> </div>
So that markup is always present, but hidden by CSS until it is needed. If I could get my CSS to work, I think all would be well. But I cannot find any clues in log files as to what the problem is - troubleshooting suggestions are welcome.