Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #31 (permalink)  
Старый 08.03.2021, 17:19
Интересующийся
Отправить личное сообщение для karaul Посмотреть профиль Найти все сообщения от karaul
 
Регистрация: 17.02.2021
Сообщений: 27

Надо чтото вроде
xhr.setRequestHeader("X-CSRFToken", csrftoken);
но где взять этот csrftoken ?

С другой стороны, если внешний сайт мне посыоает данные, csrftoken уже есть где-то
Ответить с цитированием
  #32 (permalink)  
Старый 08.03.2021, 17:36
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,692

Я думаю не получится считать файл, если страница берется с локального компьютера используя XMLHttpRequest или fetch.
Там идет проверка протоколов по которым получена страница. А если она локальная (from origin 'null'), то у нее нет протокола и он никогда не будет действительным и подходящим .
То, что она считывается браузером при указании в адресной строке - это совсем другое. Там таких проверок нет. Также как и при считывание с помощью <script>
Ответить с цитированием
  #33 (permalink)  
Старый 08.03.2021, 19:33
Интересующийся
Отправить личное сообщение для karaul Посмотреть профиль Найти все сообщения от karaul
 
Регистрация: 17.02.2021
Сообщений: 27

Спасибо за ответ. Он укрепил мою уверенность что я рою в верном направлении

В итоге нарыл пакет на питоне для соединения с гарминовским сайтом и закачки файлов - т.е. пакет делает то что мне надо. Для закачки он использует тот же URL
https://github.com/petergardfjall/garminexport

при запуске пакета сначала идет авторизация, потом там есть код типа
def _get_csrf_token(self):
        """Retrieves a Cross-Site Request Forgery (CSRF) token from Garmin's login
        page. The token is passed along in the login form for increased
        security."""
        log.info("fetching CSRF token ...")
        resp = self.session.get(SSO_LOGIN_URL, params=self._auth_params())
        if resp.status_code != 200:
            raise ValueError("auth failure: could not load {}".format(SSO_LOGIN_URL))
        # extract CSRF token
        csrf_token = re.search(r'<input type="hidden" name="_csrf" value="(\w+)"',
                               resp.content.decode('utf-8'))
        if not csrf_token:
            raise ValueError("auth failure: no CSRF token in {}".format(SSO_LOGIN_URL))
        return csrf_token.group(1)
Ответить с цитированием
  #34 (permalink)  
Старый 09.03.2021, 17:06
Интересующийся
Отправить личное сообщение для karaul Посмотреть профиль Найти все сообщения от karaul
 
Регистрация: 17.02.2021
Сообщений: 27

Питон делает из своей консоли для авторизации на внешнем сайте Гармине так
headers = {'origin': 'https://sso.garmin.com'}
и там все работает
Если я имитирую это поведение в JS с XMLHttpRequest
xhr.setRequestHeader('Origin', 'https://sso.garmin.com');
то получаю
Refused to set unsafe header Origin
Пишут что подменить заголовоr мешает броузер (хром). Незадача

Но есть еще один пакет для работы с Гармином на JS, в нем для авторизации используется axios вместо XMLHttpRequest и этот пакет работает из nodejs, и там также прописано в 'Origin', 'https://sso.garmin.com', иначе Гарминовский сайт возвращает пустую строку, а должен вернуть Cross-Site Request Forgery (CSRF) token

Если переписать браузерный код с XMLHttpRequest на axios, то получится выставить headers нужные для авторизации или это безнадежно?
Ответить с цитированием
  #35 (permalink)  
Старый 09.03.2021, 19:19
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,692

Сообщение от voraa
Я думаю не получится считать файл, если страница берется с локального компьютера используя XMLHttpRequest или fetch.
Это я опять жутко поторопился.
На самом деле МОЖНО!
Все дело в заголовках, которые посылает сервер
Вот такой простецкий сервер на nodejs

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.setHeader('Access-Control-Allow-Origin', '*');  // !important
  res.setHeader('Access-Control-Allow-Headers', 'origin, content-type, accept'); // !important
  res.end('Hello World with CORS!');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});


И вот такой html файл, расположенный локально
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" lang="ru">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" >
  <title>TESTE</title>
</head>

<body id="body">
<button type='button' id='bsend'>Send</button>
<br>
<div id='answ'>
</div>
</div>
<script>
	document.getElementById('bsend').addEventListener('click',
	async () => {
		try {
			const resp = await fetch('http://127.0.0.1:3000', {mode:'cors'})
			let str = await resp.text();
			document.getElementById('answ').innerHTML = str
			console.log(str)
		}catch (err){
			document.getElementById('answ').innerHTML=`Error ${err.name} ${err.code} ${err.message}`;
		}
	}
	);
</script>
</body>
</html>


Совершенно спокойно взаимодействуют.
Ответить с цитированием
  #36 (permalink)  
Старый 10.03.2021, 02:25
Интересующийся
Отправить личное сообщение для karaul Посмотреть профиль Найти все сообщения от karaul
 
Регистрация: 17.02.2021
Сообщений: 27

Забанили

Garmin Express Error 1006 and 1015
After attempting multiple times to log in to Garmin Express, you may receive the following errors:

"Error 1015 error RAY ID 58c1fd3vaa9dd314. You are being rate limited.  The owner of this website has banned you temporarily from accessing this website".
"Error 1006 Ray ID 5c7fda4d8a9a0d12.  Access denied.  The owner of this website (support.garmin.com) has banned your IP address (**.**.***.***).
This is the expected behavior and is displayed when too many attempts have been made to log in.  The account will be unblocked after 24 hours automatically.  Please wait 24 hours before trying to sign in again.


не так то просто отладить код при общении с чужим сайтом
Ответить с цитированием
  #37 (permalink)  
Старый 11.03.2021, 17:44
Интересующийся
Отправить личное сообщение для karaul Посмотреть профиль Найти все сообщения от karaul
 
Регистрация: 17.02.2021
Сообщений: 27

Меня разбанили и я кажется разобрался как правильно надо поступать.

Идея была в том чтобы прикрутить fitplotter к внешнему независимому сайту и скачивать оттда тренировки для анализа. Этот сайт требует аторизациии, считается что каждый пользователь эту автризацию проходит сам.

Если просто скачивать по одному файлу с сайта, то все работает, и каждый раз юзер общается с диалогом save as - куча ненужных кликов.

Если пытаться скачивать автоматически из браузера, то нельзя подменить заголовок и ничего не получается

Решение такое. Ставить свой сервер, на нем предварительно делать авторизацию на чужом сервере. Клиентская программа должна сначала обращаться к своему серверу, на котором прошла авторизация, и уже с него идти за файлами к чужому серверу.

Если чужой сервер такую практику приветствует, то он публикует свой API для доступа. Так сделала strava (и получается что если бы работал с ней, то я бы ломился в открытую дверь.) А Garmin такую практику осуждает и на гитхабе программисты матом исходят пытаясь разобраться что там Garmin придумал чтобы затруднить программную авторизацию.

У меня есть отдельные куски для сервера и клиента, надо ли их сшивать - это теперь больше политический вопрос чем технический

А если работать со strava, то она не выдает сырые файлы, из-за которых собственно весь проект начался.

И ходят слухи что Garmin якобы откроет свой АПИ.

Конечно, такие вещи надо знать до а не после. Неделя головоломки - это я дешево отлелался
Ответить с цитированием
  #38 (permalink)  
Старый 11.03.2021, 18:24
Интересующийся
Отправить личное сообщение для karaul Посмотреть профиль Найти все сообщения от karaul
 
Регистрация: 17.02.2021
Сообщений: 27

Сообщение от voraa Посмотреть сообщение
Все дело в заголовках, которые посылает сервер
Вот такой простецкий сервер на nodejs
да, именно так, нужен свой сервер для подмены заголовков.

Есть некий адрес, который становится доступным после авторизации. Допустим, я авторизовался как человек через окно браузера. До авторизации мне этот адрес недоступен, после я могу открыть его и прочитать содержимое страницы глазами и вручную скопировать, сохранить как файл и проч. Но всё вручную, автоматизировать через браузер не получается, для этого нужны серверные команды.

А если делать через сервер, то надо сначала делать авторизацию через сервер, и все команды для автоматического чтения файла посылать через этот сервер
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ищу JS разработчиков в лесу Kenjuy27 Работа 0 18.07.2018 09:06
Диалог между HTML и внешним JS в контексте расширения GoogleChrome ev1lart Events/DOM/Window 0 26.04.2017 19:25
option и время Step48_rus jQuery 38 03.07.2016 11:33
JS <-> Server Js. Severtain Общие вопросы Javascript 1 05.11.2011 15:36
Картинка обрабатывается js 4yBaK Общие вопросы Javascript 10 11.09.2011 09:28