Autorização automática no cartão Strava Heatmap



Esta postagem é uma resposta a um artigo semelhante recente. Vou tentar explicar como automatizar as ações descritas nele. E como conectar esse mapa de calor ao navegador do smartphone.

O artigo examinou como os mapas do Strava Heatmap são úteis para turistas e ciclistas e como conectar o aplicativo de navegação em um smartphone a eles usando o exemplo Osmand. O fato é que, para carregar cada parte do mapa, você precisa especificar parâmetros com dados de autorização. Algo assim:

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} 

Para obter esses dados, foi sugerido fazer login no site Strava a partir de um navegador de desktop. Como resultado, os cookies devem aparecer no navegador. Você precisa encontrar as linhas necessárias nelas e copiá-las para o endereço de solicitação. E então, insira manualmente a solicitação no Osmand para que ele possa fazer o download do mapa com sua ajuda.

No entanto, esse método não é muito conveniente, porque os dados da autorização expiram rapidamente e você deve repetir as etapas acima uma vez a cada poucos dias. Neste artigo, mostrarei como automatizar o método acima.

Adicionar um link intermediário


Para que o usuário não precise substituir o URL da solicitação no smartphone toda vez que os dados do cookie expirarem, é necessário especificar um URL inalterado. Forneci um link para meu aplicativo de servidor. Este aplicativo redirecionará o usuário para vários endereços, dependendo dos parâmetros especificados.

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

Para chegar rapidamente ao ponto, não vou me debruçar sobre a descrição desse aplicativo para servidor. Vou falar apenas sobre as principais ações dele.

Se um bloco for solicitado com um zoom de até 12 (o Stava concederá isso sem autorização), o usuário será imediatamente redirecionado para o URL público.

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

Caso contrário, uma verificação é realizada. Para acesso rápido, o aplicativo armazena em seu banco de dados a versão de trabalho mais recente do cookie. Quando recebe uma solicitação, analisa esse arquivo e cria uma URL com todos os parâmetros configurados.

Acontece algo como isto
 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_ 


Depois disso, ele envia uma solicitação HEAD para esse endereço para verificar se está disponível ou não. Se o código de status "200 Êxito" for retornado, o cookie ainda estará funcionando. O aplicativo simplesmente redireciona o usuário para esse endereço e o mapa é carregado maravilhosamente.

Mas se o código “401 Não autorizado” vier, o cookie estará desatualizado e você precisará obtê-los novamente. Nesse caso, o aplicativo executa um script para obter dados de autorização.

Autorização automática


O primeiro pensamento que vem à mente é fazer login usando a API Strava. Infelizmente, mas não fui capaz de extrair os parâmetros necessários a partir daí. Então eu decidi fazer um desvio.

Para fazer isso, usei o navegador Headless Chrome com controle remoto e escrevi um script para que "baixasse" fisicamente a página de autorização, digitei o nome de usuário e a senha e cliquei no botão.

Para fazer isso, existe uma biblioteca Puppeteer que pode controlar o navegador usando scripts Node.js. A sintaxe está bem descrita neste artigo . Eu sugiro que você se familiarize com isso.

Depois de ler, a única questão que resta é o que executar nossos scripts. Se você já é um desenvolvedor experiente do Node.js., pode pular esta seção. Quanto ao resto, posso oferecer a você o uso do serviço pronto da Apify.com . Isso evita que tenhamos que criar e configurar nosso servidor. Para nossas tarefas, basta uma conta gratuita.

Apify as configurações da conta para executar o script
Primeiro você precisa se registrar neste serviço. Depois disso, abra a seção com sua conta, vá para a seção Atores e crie um novo script.



No campo Nome, especifique o nome que será usado ao executar o script por meio da API. Clique em Salvar e vá para a página Origem.



Para iniciar o Headless Chrome, selecione a imagem do servidor “Node.js 10 + Chrome no Debian” e clique em Salvar.



Agora vá para a seção Api e copie o URL da solicitação POST, com a qual executaremos nosso script.



Você pode anexar JSON com dados para nosso script no corpo desta solicitação. Vou enviar lá meu login e senha para autorização no Strava.

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


Script para receber automaticamente dados de cookies com Strava
Agora volte para a seção Source e vá para a janela com o editor de código. Nosso script ficará assim:

 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; }); 


Ou aqui está um link para o GitHub com este script.


Fase final


Quando o script é executado, ele retornará um cookie com dados de autorização. O aplicativo do servidor o salvará em seu banco de dados e o utilizará para todas as solicitações subsequentes do cartão Strava. Até que os cookies estejam desatualizados e você não precise repetir esse procedimento novamente. Felizmente, agora tudo acontece automaticamente. Sem ações desnecessárias por parte do usuário.

Infelizmente, nem tudo é tão suave. Este método tem um ponto fraco - essa é a velocidade do trabalho. O fato é que leva algum tempo para iniciar o servidor, carregar o navegador remoto, carregar duas páginas da web e autorizar em cada uma delas. De acordo com minhas estimativas, sai mais de um minuto.

Durante esse período, o aplicativo de navegação simplesmente encerrará o download devido a um tempo limite. Portanto, é melhor retornar imediatamente o código de erro do usuário 401, para não plantar novamente uma bateria para ele.

Para fazer isso, o aplicativo do servidor definirá o sinalizador quando perceber que os dados do cookie estão desatualizados. Depois disso, ele enviará uma solicitação para executar o script e retornará imediatamente um código de erro aos usuários. Em outras palavras, o servidor ficará indisponível por um minuto.

E quando a resposta com novos cookies vier do nosso script, o aplicativo os salvará em seu banco de dados e limpará a bandeira. Depois disso, o servidor começará a funcionar normalmente e redirecionará instantaneamente o usuário para as páginas para baixar o mapa.

Resultado


O resultado do nosso trabalho tornou-se URLs imutáveis ​​com as quais os usuários podem conectar seu navegador aos mapas do 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} 

Como opção, você pode fazer predefinições prontas com esses endereços para o seu navegador. Por exemplo, nesta página , publiquei essas predefinições nos formatos Osmand, Locus, GuruMaps e Orux. Os links para baixar o mapa do Strava podem ser encontrados na seção "Conjunto completo", em "Overlay" ou "Global - OSM - Ways".

UDP: Durante o período desde a publicação do artigo, adicionei uma variante desse script que funciona através do contêiner do Docker. As instruções podem ser encontradas na minha página do GitHub .

Source: https://habr.com/ru/post/pt451620/


All Articles