Alright here is my proposal:
Use a hash of a login token as the anti-CSRF token.
Is there any security problems I am missing? Obviously this would only work for pages where the user is logged in. But that shouldn't be an issue.
Btw by "login token", I mean a securely pseudorandom string that is stored on the server and on the client in the form of a cookie that allows the server to authenticate a user without them having to enter their password each time the page changes.
Ok so it was brought up that by using this method you are decreasing security ever so slightly because the hash is based off of the login token and you could brute force to find the login token. Even tho I think this is basically impossible because of how hashes work I propose the following solution. Split the login token into 4 parts, hash the 3rd and 4th using the 2nd as a salt. This prevent the use of rainbow tables and even if an attacker somehow brute forces, they will only have 3/4th of login token. Also, the salt doesnt need to be prepended to the csrf token itself because it can be derived using the login token.
This is actually one of my preferred approaches. It makes the strength of your CSRF protection wholly dependent on the strength of your session token security, but session takeover strictly dominates CSRF in impact anyhow. The hashing means you can leave your session token in an HttpOnly cookie and not expose the session to JavaScript in any way.
However, drop everything in your last paragraph. Hashing only part of the token is strictly weaker than hashing the entire token. If you're hashing only part of the token, then brute-forcing that part is much easier (because it's shorter than the full token), and once you have a match you can not only launch CSRF attacks, you can also easily brute-force the last quarter (after all, you already brute-forced a string 3x as long) and take over the session. Salting is also meaningless in this context; the only value of a salt is to add entropy to the terribly predictable / repeatable strings people use as passwords, and if your token is fully random than what you propose would simply be taking out some amount of entropy and then putting it right back in, to no net benefit at all. You can't compute a rainbow table over possible 128-bit random token; every CPU and GPU on the planet working together would still take might-as-well-be-forever, and you couldn't actually store the table (even if some magical supercomputer could generate it) even if you turned every atom of the Earth into storage.
If you want a little bit of "feel good" security, you can HMAC the session token rather than just doing a simple hash. This is pretty pointless, though. Assuming the session token is already not at risk of brute force (because, if it is, you have WAY bigger problems than CSRF), any secure hash (I recommend something from the SHA2 or SHA3 family) is fine.
By the way, this works fine even with session token types other than the "secure random string stored in a cookie" approach. That approach has some of the problems that things like double-submit cookies try to get away from (it requires storing state on the server for each session, load balancing interferes with or at least complicates it, etc.) but this idea also works with things like JWTs. The main downside of the approach is if the session token changes (say, because a JWT was refreshed), the CSRF token changes, so you need to be careful not to reject valid requests for that reason.
Also, for what it's worth, login CSRF protection is a decent idea, on at least some sites. Anywhere a user will upload data that only they are to be allowed to see, login CSRF is a risk. Imagine a tax-filing webapp where you put in your highly-sensitive data into what you think is your own session, but somebody sneakily login-CSRFed your session to a session they have the password to. Then, after you've completed your tax return, the attacker logs in to the same account (it's theirs, after all) and downloads your returns.