Request 1Would it be possible to have all private API requests that successfully authenticate return the currently valid pin, regardless of how authentication was done (password, autologin, or pin)?
Short explanation: It makes management of private API login sessions across multiple scripts that run in random order easier.
Long explanation: After a fair amount of experimentation, I've concluded that the most robust way to handle API authentications when multiple scripts are accessing the same nation in random order is to implement a makeshift "cookie" system.
Here is how
I thought this would work: Let's say that
"cookie.txt" is a pre-specified file somewhere in the system that all scripts can access. Using this file, I make sure that
every private API call follows the same pattern shown below (I'll use a mix of curl and pseudocode for demonstration, and I skip the use of "autologin" just to keep the example simple):
- Code: Select all
your_pin = readPinFromCookie("cookie.txt")
curl -A "${your_user_agent}" -H "X-pin: ${your_pin}" -H "X-password: ${your_password}" -D "cookie.txt" "https://www.nationstates.net/cgi-bin/api.cgi?nation=${your_nation}&q=ping"
This way, before I make any private call, I'd check the "cookie" for the latest available pin. Then, I'd make a private API call providing both the pin and password. If the pin is still valid, the request will go through. If it's not, authentication will work through the password. In both cases, the returned headers will be written in the "cookie", to be used by future requests.
Unfortunately, the above does
not work. The reason is that, when authentication with pin is successful, the returned headers do not include the X-pin header. Therefore, the updated cookie will no longer have the pin, and future private requests will end up always falling back to the password. In turn, this means that, when many calls in quick succession are made, half of them will run into 409 conflicts.
This problem can be circumvented by modifying the above call pattern as follows:
- Code: Select all
your_pin = readFirstPinFromCookie("cookie.txt")
curl -A "${your_user_agent}" -H "X-pin: ${your_pin}" -H "X-password: ${your_password}" -D "cookie.txt" "https://www.nationstates.net/cgi-bin/api.cgi?nation=${your_nation}&q=ping"
appendLatestPinToCookie("cookie.txt", "${your_pin}")
This solution works, and I've already adjusted all of my code to use it. But it just seems unnecessarily complicated, and prone to result in bugs and confusion. Changing the private API responses so that the returned headers always include the currently valid pin, regardless of how authentication was performed, will help streamline the above pipeline, by making it possible to use the simpler first version.
Request 2Would it be possible to make private API requests compatible with cookies, including cookies from gameside sessions? By "compatible" I mean that: 1) the authentication information from a successful private API call can be returned through a cookie instead of headers; and 2) a cookie available from a previous gameside session or successful private API call can be used for authentication on a subsequent private API call.
Explanation: This request is for three reasons. The first reason is that it makes the pipeline I described above even simpler (and, arguably, closer to standard practice for persistent sessions, which tend to rely on cookies rather than header info). I can make all private API calls follow a pattern like:
- Code: Select all
curl -A "${your_user_agent}" -H "X-password: ${your_password}" -b "cookie.txt" -c "cookie.txt" "https://www.nationstates.net/cgi-bin/api.cgi?nation=${your_nation}&q=ping"
There's no longer need for manual processing of returned headers.
The second reason is that it'd help reduce conflicts between gameside sessions and private API sessions. To give an example: I often find myself setting a script to perform several automated tasks on my nation through the private API (backup notifications, update a whole bunch of dispatches, send a round of card gifts, etc.). These tasks can run for several minutes.
If during that time I forget that the script is running and log into my nation, I end up making many of the private API calls fail to authenticate. Sometimes I don't even need to intentionally do a new gameside login; if I so much as have the nation page open on a tab, and I navigate to that tab, I can end up interrupting the API script that is running at the same time. Allowing the private API calls to interface with the cookies used by the gameside would help greatly reduce this type of issues.
None of the above two requests are absolutely critical as far as I am concerned, as at this point my codebase works robustly enough without them. But I think they would be quality-of-life improvements for both myself, and potentially other users having similar use cases. Especially request 1 should be straightforward.
Thanks for the consideration!