Strava Heatmap卡上的自动授权



这篇文章是对最近一篇类似文章的回应。 我将尝试告诉您如何自动执行其中描述的操作。 以及如何将此热图连接到智能手机导航器。

文章探讨了Strava Heatmap地图对游客和骑自行车者如何有用,以及如何使用Osmand示例将智能手机上的导航应用程序连接到他们。 事实是,要加载每个地图,您都需要指定带有授权数据的参数。 像这样:

GET https://heatmap-external-{abc}.strava.com/tiles-auth/all/hot/{z}/{x}/{y}.png?px=256&Signature={CloudFront-Signature}&Key-Pair-Id={CloudFront-Key-Pair-Id}&Policy={CloudFront-Policy} 

要获取此数据,建议从桌面浏览器登录Strava网站。 因此,cookies应该出现在浏览器中。 您需要在其中找到所需的行,然后将其复制到请求地址。 然后,将请求手动输入Osmand,以便他可以在他的帮助下下载地图。

但是,这种方法不是很方便,因为授权数据很快就会过期,并且您必须每隔几天重复一次上述步骤。 在本文中,我将告诉您如何自动执行上述方法。

添加中间链接


为了使用户不必在Cookie数据每次到期时都替换智能手机中的请求URL,您需要指定一些未更改的URL。 我提供了到服务器应用程序的链接。 此应用程序将根据指定的参数将用户重定向到各种地址。

 https://anygis.herokuapp.com/Tracks_Strava_All/{x}/{y}/{z} 

为了快速理解这一点,我将不讨论该服务器应用程序的描述。 我只告诉你他的主要动作。

如果请求的图块的缩放比例最大为12(Stava未经授权就给出了此图块),则用户将立即重定向到公共URL。

 https://heatmap-external-a.strava.com/tiles/all/hot/10/619/318.png 

如果不是,则执行检查。 为了快速访问,该应用程序将cookie的最新工作版本存储在其数据库中。 收到请求后,它将解析该文件并创建一个设置了所有参数的URL。

原来是这样的
 https://heatmap-external-a.strava.com/tiles-auth/all/hot/10/619/318.png?px=256<b>&Signature</b>=Q47FWl1RX-5tLNK9fGfa7hdoxqwwjCLfrxwb~L3eke8h~glz5IBHmkLmu8ofh6eNWUM3usHTz4Z3rypbQGByC2jRhdzL2iJndIOu2TY9ZU34YUJV9QgMEf0L5cDHGjEsksYSVdkCqNRvOMnnzUc96wR9sktK2a0pcsI~E5eNvqjfsGbSWi6KCdfc1-~2D8t9YjbKftokhvMY20pM~PD6Y-fGYmpoTO5LOyMfIYboXnKGm29VnA9kA8LIxD-LzpADWO81i4pOMBvkVkJuLBGtO96a79P5D4tRP05DpI7y457LuKcuqRZaVQRB1L2AXgKvQgnx6nqr9T2jRAZNoy06ng__ <b>&Key-Pair-Id</b>=APKAIDPUN4QMG7VUQPSA <b>&Policy</b>=eyJTdGF0ZW1lbnQiOiBbeyJSZXNvdXJjZSI6Imh0dHBzOi8vaGVhdG1hcC1leHRlcm5hbC0qLnN0cmF2YS5jb20vKiIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTU1ODUwODc2Mn0sIkRhdGVHcmVhdGVyVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNTU3Mjg0NzYyfX19XX0_ LzpADWO81i4pOMBvkVkJuLBGtO96a79P5D4tRP05DpI7y457LuKcuqRZaVQRB1L2AXgKvQgnx6nqr9T2jRAZNoy06ng__ https://heatmap-external-a.strava.com/tiles-auth/all/hot/10/619/318.png?px=256<b>&Signature</b>=Q47FWl1RX-5tLNK9fGfa7hdoxqwwjCLfrxwb~L3eke8h~glz5IBHmkLmu8ofh6eNWUM3usHTz4Z3rypbQGByC2jRhdzL2iJndIOu2TY9ZU34YUJV9QgMEf0L5cDHGjEsksYSVdkCqNRvOMnnzUc96wR9sktK2a0pcsI~E5eNvqjfsGbSWi6KCdfc1-~2D8t9YjbKftokhvMY20pM~PD6Y-fGYmpoTO5LOyMfIYboXnKGm29VnA9kA8LIxD-LzpADWO81i4pOMBvkVkJuLBGtO96a79P5D4tRP05DpI7y457LuKcuqRZaVQRB1L2AXgKvQgnx6nqr9T2jRAZNoy06ng__ <b>&Key-Pair-Id</b>=APKAIDPUN4QMG7VUQPSA <b>&Policy</b>=eyJTdGF0ZW1lbnQiOiBbeyJSZXNvdXJjZSI6Imh0dHBzOi8vaGVhdG1hcC1leHRlcm5hbC0qLnN0cmF2YS5jb20vKiIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTU1ODUwODc2Mn0sIkRhdGVHcmVhdGVyVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNTU3Mjg0NzYyfX19XX0_ 


之后,它将HEAD请求发送到该地址以检查其是否可用。 如果返回状态码“ 200 Success”,则cookie仍在工作。 该应用程序只需将用户重定向到该地址,地图就可以精美地加载。

但是,如果到达代码“ 401未经授权”,则cookie已过期,您需要再次获取它们。 在这种情况下,应用程序将运行脚本以获取授权数据。

自动授权


首先想到的是使用Strava API登录。 las,但是我无法从那里提取必要的参数。 所以我决定绕道而行。

为此,我使用了带遥控器的无头Chrome浏览器,并为其编写了脚本,以便它“物理”下载授权页面,在此处输入用户名和密码,然后单击按钮。

为此,有一个Puppeteer库可以使用Node.js脚本控制浏览器。 本文对语法进行了很好的描述。 我建议您熟悉一下它。

阅读完之后,唯一的问题仍然是在什么上运行我们的脚本。 如果您已经是经验丰富的Node.js开发人员,则可以跳过本部分。 对于其他情况,我可以为您提供使用Apify.com提供的现成服务。 这使我们不必创建和配置服务器。 对于我们的任务,免费帐户就足够了。

验证帐户设置以运行脚本
首先,您需要注册此服务。 之后,使用您的帐户打开该部分,转到Actors部分并创建一个新脚本。



在“名称”字段中,指定通过Api运行脚本时将使用的名称。 单击“保存”,然后转到“源”页面。



要启动Headless Chrome,请选择“ Node.js 10 + Debian上的Chrome”服务器映像,然后单击“保存”。



现在转到Api部分并复制POST请求的URL,我们将使用该URL运行脚本。



您可以将JSON和我们脚本的数据附加到此请求的正文中。 我将把我的登录名和密码发送到那里,以便在Strava上进行授权。

 { "email": "your_nick@gmail.com" , "password": "Your_Password" } 


使用Strava自动接收Cookie数据的脚本
现在回到“源代码”部分,并使用代码编辑器转到窗口。 我们的脚本如下所示:

 const Apify = require('apify'); Apify.main(async () => { //  //     JSON const input = await Apify.getInput(); if (!input || !input.email || !input.password) throw new Error('Invalid input, must be a JSON object with the "email" and "password" field!'); //     const browser = await Apify.launchPuppeteer(); //  1 -    cookie //    const page1 = await browser.newPage(); await page1.setViewport({width: 1280, height: 1024}); //     await page1.goto('https://www.strava.com/login', {waitUntil: 'networkidle2'}); //   html-  /    await page1.waitForSelector('form'); await page1.type('input#email', input.email); await page1.type('input#password', input.password); //  ,  , //   ,       await page1.waitFor(200); //        await page1.evaluate(()=>document .querySelector('button#login-button') .click() ); //      cookie  await page1.waitForNavigation(); const sessionFourCookie = await page1.cookies(); //  2 -   cookie      //    const page2 = await browser.newPage(); //      ,   . //  ,        cookie await page2.setCookie(...sessionFourCookie); await page2.goto('https://heatmap-external-a.strava.com/auth'); //     cookie const cloudfontCookie = await page2.cookies(); //  //    await browser.close(); //    cookie    return cloudfontCookie; }); 


或者这是使用此脚本的GitHub 链接


最后阶段


脚本运行时,它将返回包含授权数据的cookie。 服务器应用程序会将其保存到其数据库中,并将其用于所有随后的Strava卡请求。 在cookie过期之前,您无需再次重复此过程。 幸运的是,现在一切都会自动进行。 用户无需采取不必要的措施。

las,并非一切都那么顺利。 这种方法有一个弱点-这就是工作速度。 事实是,启动服务器,加载远程浏览器,加载两个网页并在每个网页上进行授权需要花费一些时间。 据我估计,一分钟以上就出来了。

在这段时间内,导航应用程序将因超时而简单地终止下载。 因此,最好立即返回用户错误代码401,以免再次为他装电池。

为此,服务器应用程序在意识到Cookie数据已过期时将设置该标志。 之后,它将发送运行脚本的请求,并立即将错误代码返回给用户。 换句话说,服务器将在一分钟内不可用。

当带有新Cookie的响应来自我们的脚本时,应用程序会将它们保存到其数据库中并清除该标志。 之后,服务器将再次照常开始工作,并立即将用户重定向到用于下载地图的页面。

结果


我们工作的结果变成了不变的URL,用户可以使用它们将其导航器连接到Strava地图。

 https://anygis.ru/api/v1/Tracks_Strava_All/{x}/{y}/{z} https://anygis.ru/api/v1/Tracks_Strava_Ride/{x}/{y}/{z} https://anygis.ru/api/v1/Tracks_Strava_Run/{x}/{y}/{z} https://anygis.ru/api/v1/Tracks_Strava_Water/{x}/{y}/{z} https://anygis.ru/api/v1/Tracks_Strava_Winter/{x}/{y}/{z} https://anygis.ru/api/v1/Tracks_Strava_All_Bluered/{x}/{y}/{z} https://anygis.ru/api/v1/Tracks_Strava_Ride_Bluered/{x}/{y}/{z} https://anygis.ru/api/v1/Tracks_Strava_Run_Bluered/{x}/{y}/{z} https://anygis.ru/api/v1/Tracks_Strava_Water_Bluered/{x}/{y}/{z} https://anygis.ru/api/v1/Tracks_Strava_Winter_Bluered/{x}/{y}/{z} 

作为一种选择,您可以使用这些地址为导航器进行现成的预设。 例如, 在此页面上,我以Osmand,Locus,GuruMaps和Orux的格式发布了此类预设。 下载Strava地图的链接可以在“覆盖”或“全局-OSM-方式”下的“完整集”部分中找到。

UDP:自本文发表以来,我添加了此脚本的一种变体,可通过Docker容器使用。 这些说明可以在我的GitHub页面上找到

Source: https://habr.com/ru/post/zh-CN451620/


All Articles