costastf / locationsharinglib

A library to retrieve coordinates from an google account that has been shared locations of other accounts.
MIT License
170 stars 29 forks source link

automatic fetching of cookie? #113

Closed gtoal closed 1 year ago

gtoal commented 1 year ago

There was a similar cookie problem in making calls to the Amazon Alexa interface ( see https://blog.loetzimmer.de/2017/10/amazon-alexa-hort-auf-die-shell-echo.html and https://github.com/thorsten-gehrig/alexa-remote-control/tree/master ) which that project was able to solve without user interaction - if your session has expired, it fetches a new cookie automatically. The method seems reliable, I've been using it to output speech from my linux via the Alexa for over a year now. Would something like this be possible for your project as well?

costastf commented 1 year ago

Hi @gtoal, thanks for the info! That works because the service supports refresh tokens so you can ask for one. There is no indication for that working on google. There is a discussion in https://github.com/costastf/locationsharinglib/issues/110 where I implemented a cookie monitoring solution in the https://github.com/costastf/locationsharinglib/tree/feature-observe-cookies branch to see what is happening and if there is any refresh of any kind. If that yields anything we can implement something useful. I am very doubtful to be honest that it will, i have a feeling that google sends the cookies over and then they just expire and you need to relogin. If you want to help with figuring that out you can run the branch code and see the info logging messages for any incoming set-cookie and we can figure out how things work on the back end.

gtoal commented 1 year ago

Actually I use a utility called Fiddler for examining traffic; it seems to be quite effective. ( https://www.telerik.com/fiddler ) And indeed it could be scripted to find and save the cookies, but it's a Windows program and my always-on server here is Linux. Anyway, as an alternative approach, could the login be scripted instead?

costastf commented 1 year ago

No, I am afraid not. That is how I started. The login was automatic by username and password but Google has too many different implementations throughout the world and it was just to much work to try to keep up with all of them. That is why the project reverted to accepting cookies

costastf commented 1 year ago

I will be closing this as implementing automatic authentication is not something feasible.

gtoal commented 1 month ago

I'm not sure if I can add comments to a closed issue but I'll try :-) I've made quite a bit of progress in accessing the cookie on linux automatically through using a combination of Xvfb and xdotool to script a GUI session of firefox without actually using a real gui. sqlite3 then extracts the cookie information from firefox's local sql database, "cookies.sqlite". It's not a robust implementation yet (firefox frequently puts up a prompt box when first started, asking to either start a new session or restore the session, and my scripting at this point is somewhat naive) but it shows promise. Maybe there's an easier way with lynx and expect, but I thought I'd try this first as learning how to script a GUI program on linux might be something that will come in useful again (and I'm not at all sure that a map-based web site would even try to cooperate with a text-based web browser!)

costastf commented 1 month ago

Sounds like you are having fun 😊! Nice to hear, share any progress you make, someone might be interested to implement it for themselves too!

gtoal commented 1 month ago

Well, this solution works for me. Install the free edition of Fiddler. The script below captures the actual location data, not the cookie. (Though no doubt the cookie is in there somewhere and you could use that approach if you preferred to).

Replace the OnBeforeResponse function in the default script with this code:

    static var seq: int = 9999; // unfortunately reset on every restart
    static function OnBeforeResponse(oSession: Session) {
        if (m_Hide304s && oSession.responseCode == 304) {
            oSession["ui-hide"] = "true";
        }
        if (oSession.HostnameIs("www.google.com")) {
            if (Regex.IsMatch(oSession.PathAndQuery,
                '/maps/rpc/locationsharing/read?authuser=([^&]+)&hl=([^&]+)&gl=([^&]+)&pb=([^&]+)'),
                RegexOptions.IgnoreCase) {
                // not doing anything with params for now
                seq = seq+1;
                oSession.SaveResponseBody("C:\\temp\\loc"+seq+".txt"); // make sure you have created C:\temp
            }
        }
    }

Then open Google maps in your web browser, log in, and just leave both Fiddler and Google Maps running. Have some external program monitor the directory and get the shared location data out of the files that are saved there regularly (and delete the older files as they're replaced with new data). Maybe even send it to MQTT if you want.

(I'm not sure if these updates are sent if the person sharing their location with you is outside the map area so you may want to zoom out so that your entire continent is visible to ensure that they are too. Likewise, hiding the browser window may also stop updates being sent, or maybe just not as frequently, so I suggest just leaving it full-screened)

Unfortunately this only works on Windows, and I haven't been able to create any similar interception on Linux despite spending quite some time messing around with mitmproxy - problems with HTTP Strict Transport Security among other things. Fortunately I have a crappy old Windoze portable that still works enough to do this that I can dedicate to the task.