-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
couchdb: Unexpected Unauthorized if PUT intervals closely match couchdb cookie timeout #657
Comments
LiberaChat #couchdb people suggest to run using basic http auth to see if the problem disappears - I will try this (not sure how to make kivik do that, though) |
This should help: https://github.com/go-kivik/kivik/wiki/Authentication#http-basic-auth |
This is an inherent problem with many HTTP-based services that uses cookies for authentication. We can refresh the cookie on every request, but if there are no requests, there's no way to refresh the cookie. There are basically two possible approaches:
If it's reasonable in your app, you could have some background task do a CouchDB ping every N seconds (where N is reasonably less than your cookie expiration time). Maybe I could add this as an option to Kivik, as well. 🤔 I could have kivik fire off a goroutine that sends a simple ping request to CouchDB when the cookie is nearing expiration. I think it would have to be an opt-in feature--probably an option to the CookieAuth type. What do you think? |
I don't fully understand the problem - if I wait longer, everything works fine, e.g. increasing the timout to 90 seconds and it will always re-authenticate:
Possibly because kivik "knows" the cookie has expired? It appears asif it only fails during this sweet spot where the interval ~ timeout. What if kivik would just re-authenticate if the cookie expires not just now, but also in the next few seconds? |
I just pushed a change to v3.2.10 to re-auth if kivik knows the cookie will expire within the next 60 seconds. This should eliminate any problems caused by clocks being slightly out of sync. I don't know if that's enough to address this, but if you're able to try that and let me know if it changes things for you, that could be nice. It still won't solve any problem of long delays between requests, but it sounds like that's not your problem anyway. |
FWIW, this is not about clock sync - the error occurs when the sample code and couchdb run on the same machine. It's probably that slight interval between checking pre-request and the request actually ending up in couchdb. Long delays actually work fine - the problem does not occur when pausing for ~50 sec or ~90 sec, only specificaly ~60 sec I would expect your fix to work but it doesn't
|
Very curious. I'll spend some additional time investigating with your repro case when I have a moment. |
FWIW, this is not about clock sync - the error occurs when the sample code and couchdb run on the same machine. It's probably that slight interval between checking pre-request and the request actually ending up in couchdb. Long delays actually work fine - the problem does not occur when pausing for ~50 sec or ~90 sec, only specificaly ~60 sec I would expect your fix to work but it doesn't
|
(most likely this is a dead end - don't put too much time in this comment) I'm doing some local testing/debugging but I can't make much sense. My cookies always have Expires.IsZero() true, making shouldAuth() false. The But if I inspect the calls with strace I do see a cookie being set with a valid expiration. (may update this comment with additional findings) I'm trying to make sense of this al but can't really. I don't understand why the Expires isn't set properly from the response. I've added a wrapping CookieJar that intercepts and dumps the cookies as follows (chttpd.go)
This produces the following output when running the sample code:
It retrieves and dumps the cookies immediately after set, and the expires is gone
(the cookie hasn't expired at this point) I'm probably missing something obvious here, and I'm probably approaching it incorrectly, but for me it's time to let this rest for now :) updateOkay, so I couldn't let it rest. CookieJar.Cookies() creates fresh new cookies and doesn't include Expires, see https://github.com/golang/go/blob/master/src/net/http/cookiejar/jar.go#L221
But even when I add Expires there, the problem remains. Giving up for now, for real. |
I'm able to reproduce this locally. That behavior of the cookie jar is strange. I'll ponder a proper solution. I hope it won't mean reimplementing the cookie jar myself, but that could be an option if all else fails. |
I think I have a fix with go-kivik/couchdb#285 |
Unfortunately that doesn't fix it for my reproduction code - it still (eventually) results in the Unauthorized error. It might be that it runs slightly longer, but after a few minutes it will crash I added an extra interval to the expiration check in shouldAuth(), that doesn't seem to make a difference. (I double checked using Println() that I am truely using the expiredSessions branch) |
We have been getting unexpected Unauthorized responses when inserting documents at a really slow pace. The interval of those insertions seem to closely match the cookie timeout on couchdb.
To reproduce this, we've set the couch_httpd_auth.timeout to 60 (seconds) on a couch 3.1.1 instance (not in docker) and ran the following code:
running this
The Coouchd debug logs show
I am aware that there is an auth/cookie related fix in go-kivik/couchdb#280 that has been merged, but even with this change the problem occurs
github.com/go-kivik/couchdb/v4 v4.0.0-20210603203912-7a5e3ef402b2
should contain that fix, right?The text was updated successfully, but these errors were encountered: