Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Аутентификация и HTTP-заголовок (https://javascript.ru/forum/node-js-io-js/83444-autentifikaciya-i-http-zagolovok.html)

Raadsert 09.12.2021 18:43

Аутентификация и HTTP-заголовок
 
Здравствуйте.

Сейчас разбираюсь с написанием системы авторизации, прочитал множество статей и не могу понять одного момента.

Для подтверждения того что пользователь уже проходил авторизацию создаётся JWT токен и отправляется в клиент.
Сам же токен в дальнейшем берётся из request заголовка HTTP, и главный вопрос в том как именно токен попадает в этот заголовок? Какие то операции должны проходить на стороне клиента?

Видел как некоторые используют перехват из пакета axios, но я не хотел бы загружать проект целым пакетом ради одной функции.

Буду очень благодарен за помощь.

MallSerg 09.12.2021 21:00

>> главный вопрос в том как именно токен попадает в этот заголовок?
Клиент сам добавляет в заголовок.
Обычно помощью специальных функций доступных у клиента.
т.е. клиент специально вызывает функции которые добавляют заголовок к HTTP запросу.

>> Какие то операции должны проходить на стороне клиента?
Клиент должен добавить заголовок и его значение.
Практически во всех видах клиента это выглядит как

создать HTTP_запрос = новый HTTP_запрос();
HTTP_запрос.ДобавитьЗаголово к (ИмяЗаголовка , ЗначениеЗоголовка);
HTTP_запрос.ТекстЗапроса = КакоцтаТекстЗапроса;
HTTP_запрос.Отправить();

Raadsert 10.12.2021 00:42

Цитата:

Сообщение от MallSerg (Сообщение 542317)
>> главный вопрос в том как именно токен попадает в этот заголовок?
Клиент сам добавляет в заголовок.
Обычно помощью специальных функций доступных у клиента.
т.е. клиент специально вызывает функции которые добавляют заголовок к HTTP запросу.

>> Какие то операции должны проходить на стороне клиента?
Клиент должен добавить заголовок и его значение.
Практически во всех видах клиента это выглядит как

создать HTTP_запрос = новый HTTP_запрос();
HTTP_запрос.ДобавитьЗаголово к (ИмяЗаголовка , ЗначениеЗоголовка);
HTTP_запрос.ТекстЗапроса = КакоцтаТекстЗапроса;
HTTP_запрос.Отправить();

Но если какая то операция по присваиванию заголовка проходит через клиент как тогда проверять доступ к определенной странице, не через промежуточную страницу ведь?

Извиняюсь за глупые вопросы, вынужденная мера так как в статьях об операциях со стороны клиента никто не рассказывал.

MallSerg 10.12.2021 04:18

В клиент серверной архитектуре подразумевается что клиент только запрашивает а все операции совершает сервер.

При запросе сервер отвечает что доступ запрещен.
В протоколе http для этого предусмотрены специальные статус коды
https://ru.wikipedia.org/wiki/%D0%A1...%B8%D1%8F_HTTP

Raadsert 10.12.2021 17:48

Цитата:

Сообщение от MallSerg (Сообщение 542325)
В клиент серверной архитектуре подразумевается что клиент только запрашивает а все операции совершает сервер.

При запросе сервер отвечает что доступ запрещен.
В протоколе http для этого предусмотрены специальные статус коды
https://ru.wikipedia.org/wiki/%D0%A1...%B8%D1%8F_HTTP

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

Raadsert 09.02.2022 23:19

Цитата:

Сообщение от MallSerg (Сообщение 542325)
В клиент серверной архитектуре подразумевается что клиент только запрашивает а все операции совершает сервер.

При запросе сервер отвечает что доступ запрещен.
В протоколе http для этого предусмотрены специальные статус коды
https://ru.wikipedia.org/wiki/%D0%A1...%B8%D1%8F_HTTP

А вы не могли бы подсказать, как на сервере нужно принимать запросы с присвоенными заголовками?

К примеру у меня в клиенте имеется такой код:
let request = new XMLHttpRequest();
request.open('GET', document.location, false);
request.setRequestHeader('Test', 'token');
request.send(null);
request.getAllResponseHeaders().toLowerCase();


Как на сервере принять этот код и обработать для последующего вывода нужных страниц?

ksa 10.02.2022 09:13

Цитата:

Сообщение от Raadsert
Как на сервере принять этот код и обработать для последующего вывода нужных страниц?

Так смотря какой у тебя сервер... :)
На Node.js принимающая сторона имеет объект request в котором есть ключ headers.
Вот в нем и содержатся все данные заголовка, так же в виде пар ключ-значение...

ksa 10.02.2022 09:19

Raadsert, обработка и доступ к страницам также сильно зависит от того на чем у тебя организован клиент...
Например для Реакт, Вью или Ангулар достаточно изменить нужное состояние, если клиент не авторизован.

Если использовать связку Node.js + его шаблонизатор (например PUG), можно сделать редирект на страничку "вы не авторизованы"...
А с нее можно попасть только на регистрацию.

Т.е. фантазию можно развивать на таких делах. :D

micscr 10.02.2022 09:52

Цитата:

Сообщение от Raadsert (Сообщение 542327)
Это понятно. При запросе доступа к определённой странице на сервер отправляются некоторые данные в том числе и заголовки, если нужного заголовка авторизации с токеном нет, сервер не даёт доступа к странице. На сколько я понял, токен сохраняется в куки а после передаётся в HTTP заголовок, но где и как эти заголовки присваиваются я понять не могу. Если они присваиваются на стороне сервера и там же проверяются, то не понимаю почему тогда просто не взять токен из куки без передачи и повторной проверки на сервере.

Токен не сохраняется в куки.
Эти токены существуют для rest api, а они без состояния, т.е. ни на сессии ни на куки не рассчитывай, с каждым запросом надо тащить нужную инфу о пользователе.

Все работает примерно так:
- клиент хочет обратиться к api
- клиент у себя где то хранит токен доступа, да хоть в переменной какой если это SPA, или в localStorage
- итак, клиент видит что токена нет
- он по api обращается на страницу аутентификации, с именем и паролем, и сервер ему отдает этот токен
- в этом токене будет храниться все достаточное чтобы клиенту залогиниться в api
- вот и получается что достаточно ему с этим токеном в заголовке заходить, на сервере он будет залогинен

Raadsert 10.02.2022 15:41

Цитата:

Сообщение от MallSerg (Сообщение 542325)
В клиент серверной архитектуре подразумевается что клиент только запрашивает а все операции совершает сервер.

При запросе сервер отвечает что доступ запрещен.
В протоколе http для этого предусмотрены специальные статус коды
https://ru.wikipedia.org/wiki/%D0%A1...%B8%D1%8F_HTTP

Цитата:

Сообщение от ksa (Сообщение 543635)
Raadsert, обработка и доступ к страницам также сильно зависит от того на чем у тебя организован клиент...
Например для Реакт, Вью или Ангулар достаточно изменить нужное состояние, если клиент не авторизован.

Если использовать связку Node.js + его шаблонизатор (например PUG), можно сделать редирект на страничку "вы не авторизованы"...
А с нее можно попасть только на регистрацию.

Т.е. фантазию можно развивать на таких делах. :D

У меня Node.js и express, без шаблонизаторов, без "Реакт", "Вью" или "Ангулар". Я вместе с первым запросом к странице, к примеру "/auth", высылаю ответ в качестве пустой страницы с js файлом (в нём код тот что выше) где он формирует заголовок и отправляет его на сервер по текущему адресу, но каким образом на сервере можно получить этот заголовок понять не могу. Обычный запрос app.get никак не реагирует если я повторно отправляю файл html но уже с информацией о заголовке.

ksa 10.02.2022 18:04

Raadsert, есть подозрение что ты просто говнокодишь...

Как вариант сделай простенькую модель сайта.
На ней можно буде лучше понять чего ты так гоношишь.

ksa 10.02.2022 18:11

Raadsert, вот почитай доку...
https://nodejsdev.ru/doc/request-object/

Вот пример авторизации...
https://nodejsdev.ru/doc/jwt/

Raadsert 10.02.2022 22:43

Цитата:

Сообщение от ksa (Сообщение 543651)
Raadsert, вот почитай доку...
https://nodejsdev.ru/doc/request-object/

Вот пример авторизации...
https://nodejsdev.ru/doc/jwt/

Я определённо пишу говнокод, не намеренно. Скорее всего я неправильно передаю скрипт в клиент для передачи заголовка(разумеется это не скрипт для проверки авторизации, так я решил попробовать вообще передать какую то информацию в заголовках):
app.use(express.static(`${__dirname}/auth`), (req, res, next) => {
  res.status(200).sendFile(path.resolve(__dirname, 'auth', 'index.html'));
  next()
})

app.use(express.static(`${__dirname}/auth`), (req, res, next) => {
  if (req.headers.test) {
    req.user = req.headers.test
    next()
  }
  next()
})

app.get('/auth', (req, res) => {
  if (req.user) return res.status(200).send(`<h1>${req.user}</h1>`);
  else return res.status(200).send(`<h1>None</h1>`);
})


index.html загружает скрипт XML. До этого загружал файл в app.get .
Подскажите, что я делаю не так?

ksa 11.02.2022 08:32

Цитата:

Сообщение от Raadsert
что я делаю не так?

Ты лучше напиши что ты собрался этим кодом получить?

ksa 11.02.2022 08:40

Raadsert, такую вот статейку почитай...
https://medium.com/nuances-of-progra...s-80915da83c60

Raadsert 11.02.2022 16:22

Цитата:

Сообщение от ksa (Сообщение 543655)
Ты лучше напиши что ты собрался этим кодом получить?

Я собирался получить значение http-заголовка "test", который присваивается в index.html:

let request = new XMLHttpRequest();
request.open('GET', document.location, false);
request.setRequestHeader('test', 'test-info');
request.send(null);
request.getAllResponseHeaders().toLowerCase();


Вот тут, если заголовок существует, он должен передать его к req.user:

app.use(express.static(`${__dirname}/auth`), (req, res, next) => {
  if (req.headers.test) {
    req.user = req.headers.test
    next()
  }
  next()
})


После чего в app.get, если req.user существует, вместо обычной страницы index.html вывести информацию из http-заголовка "<h1>${req.user}</h1>":

app.get('/auth', (req, res) => {
  if (req.user) return res.status(200).send(`<h1>${req.user}</h1>`);
  else return res.status(200).send(`<h1>None</h1>`);
})


Дело в том что последняя часть не возвращает h1 с каким бы то ни было значением. Почему так происходит, и как вернуть результат присваиваемого http-заголовка через сервер обратно в клиент?

p.s. На сколько я понял так и работает система аутентификации, только клиент отправляет jwt-токен на сервер (вместо заголовка "test": "test-info"), он сравнивает токен с тем что хранится у него и при положительном результате отправляет клиенту некую информацию с ограниченным доступом (в случае выше это просто h1 с информацией из http-заголовка "test").

ksa 11.02.2022 18:31

Raadsert, я тебе статейку выше для чего дал?
Для начала просто почитай для чего
Цитата:

Сообщение от Raadsert
express.static

Потом нужно понять что бывает после
Цитата:

Сообщение от Raadsert
res.status(200).sendFile(...)

Тогда может быть придет понимание почему
Цитата:

Сообщение от Raadsert
последняя часть не возвращает h1 с каким бы то ни было значением

;)

Т.е. просто писать аглицкие слова в произвольном порядке - не значит программировать.

Raadsert 11.02.2022 22:02

Цитата:

Сообщение от ksa (Сообщение 543666)
Raadsert, я тебе статейку выше для чего дал?
Для начала просто почитай для чего


Потом нужно понять что бывает после


Тогда может быть придет понимание почему

;)

Т.е. просто писать аглицкие слова в произвольном порядке - не значит программировать.

express.static
используется совместно с "use" для указания директории статичных файлов, я знаю.

res.status(200).sendFile(...)
"sendFile" используется для отправки файлов в клиент, иначе как мне доставить скрипт на сторону клиента?! Дело в том что я неправильно указал статут ответа? Я всё прочитал, но всё равно не могу понять. Единственное что мне приходит в голову это то что ответ с сервера я должен обрабатывать скриптом на стороне клиента и все передаваемые сервером данные размещать при помощи скрипта.

ksa 12.02.2022 09:48

Что-то туго идет... :(

Как только ты объявил некую директорию через express.static, файлы из нее будет отправлять сам экспресс...

Как только что-то отправили клиенту - вся твоя дальнейшая "обработка" теряет всякий смысл.

Если ты хочешь что-то взять из заголовка и запихать его куда-то - это нужно делать после основных обработчиков/парсеров экспресс.

Вот тебе еще ссылочка на доку про сам экспресс
https://expressjs.com/ru/guide/routing.html

Raadsert 12.02.2022 19:48

Цитата:

Сообщение от ksa (Сообщение 543670)
Что-то туго идет... :(

Как только ты объявил некую директорию через express.static, файлы из нее будет отправлять сам экспресс...

Как только что-то отправили клиенту - вся твоя дальнейшая "обработка" теряет всякий смысл.

Если ты хочешь что-то взять из заголовка и запихать его куда-то - это нужно делать после основных обработчиков/парсеров экспресс.

Вот тебе еще ссылочка на доку про сам экспресс
https://expressjs.com/ru/guide/routing.html

Я понял... express.static просто даёт возможность переходить к файлам по ссылке без необходимости отправлять каждый через sendFile. А после самой отправки send или sendFile я уже не смогу отправить новую информацию, правильно? Но как тогда отправить на ту же страницу результат с новоиспеченным заголовком "test"?

ksa 12.02.2022 20:42

Цитата:

Сообщение от Raadsert
правильно?

Начинаем продвигаться вперед! :yes:

Цитата:

Сообщение от Raadsert
Но как тогда отправить на ту же страницу результат с новоиспеченным заголовком "test"?

Нужно правильно обрабатывать все запросы на сервер и понимать как он (сервер) работает...

Для работы с заголовками можно использовать промежуточные обработчики
https://expressjs.com/ru/guide/writing-middleware.html

После ПО нужно правильно обработать сам запрос...
Это уже по предыдущей ссылке (маршрутизация) можно будет сделать, добавив обработку полученных данных из заголовка.

Raadsert 13.02.2022 15:21

Цитата:

Сообщение от ksa (Сообщение 543683)
Начинаем продвигаться вперед! :yes:


Нужно правильно обрабатывать все запросы на сервер и понимать как он (сервер) работает...

Для работы с заголовками можно использовать промежуточные обработчики
https://expressjs.com/ru/guide/writing-middleware.html

После ПО нужно правильно обработать сам запрос...
Это уже по предыдущей ссылке (маршрутизация) можно будет сделать, добавив обработку полученных данных из заголовка.

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

ksa 14.02.2022 07:34

Raadsert, тут кагбэ нужно разделить задачи и определиться что и в какой последовательности ты собираешься делать... :blink:

У тебя уже фигурируют несколько слов в непонятной для меня последовательности. Это:
- файл
- заголовок
- ответ
- реквест
- клиент
- скрипт

Raadsert 14.02.2022 12:51

Цитата:

Сообщение от ksa (Сообщение 543699)
Raadsert, тут кагбэ нужно разделить задачи и определиться что и в какой последовательности ты собираешься делать... :blink:

У тебя уже фигурируют несколько слов в непонятной для меня последовательности. Это:
- файл
- заголовок
- ответ
- реквест
- клиент
- скрипт

Тут дело в том что я хочу получить не любой существующий заголовок а именно тот который был создан на стороне клиента. Чтобы создать заголовок клиенту нужно отправить (res.send(...)) html-файл со скриптом для создания самого заголовка, так? Но после вызова res.send(...) всё останавливается и вернуть любую информацию по тому же адресу в котором был отправлен (res.send(...)) html-файл не получиться. Тут я и запутался.

p.s Клиент это ведь сам сайт, то есть, та часть что сервер отправляет в качестве index.html со встроенными скриптами и является клиентом, верно?

ksa 14.02.2022 18:44

Цитата:

Сообщение от Raadsert
Тут дело в том что я хочу получить не любой существующий заголовок а именно тот который был создан на стороне клиента.

Заголовок приходит только от клиента, это кагбэ аксиома. ;)

Я тебе для чего давал ссылку на роутинг?
Роутинг он кагбэ много возможностей имеет. :)

Вот ты и должен с ним определиться.
Если нужно вернуть статику - это можно сделать используя express.static...
Обработать заголовки - простым промежуточным обработчиком...

А отправить запрос со статики можно либо поменяв метод, либо весь УРЛ.

Фантазию нужно развивать и учебники читать. Доки они кагбэ уже для понимающих написаны.
Если понимания нет - нужно учебники читать. Там и примеров будет много показано.

В противном случае ты так и будешь ходить "кругами". :(

Raadsert 14.02.2022 20:29

Цитата:

Сообщение от ksa (Сообщение 543737)
Заголовок приходит только от клиента, это кагбэ аксиома. ;)

Я тебе для чего давал ссылку на роутинг?
Роутинг он кагбэ много возможностей имеет. :)

Вот ты и должен с ним определиться.
Если нужно вернуть статику - это можно сделать используя express.static...
Обработать заголовки - простым промежуточным обработчиком...

А отправить запрос со статики можно либо поменяв метод, либо весь УРЛ.

Фантазию нужно развивать и учебники читать. Доки они кагбэ уже для понимающих написаны.
Если понимания нет - нужно учебники читать. Там и примеров будет много показано.

В противном случае ты так и будешь ходить "кругами". :(

А можете подсказать несколько подобных книг?

Мне просто при помощи роутеров создавать заголовок? Мне кажется это бессмысленным если речь идёт о передаче в заголовке токена. Я создавал заголовок через XML после того как загрузится страница на которую был осуществлён переход, это не правильный способ? Дело в том что я наблюдал за тем как этот процесс проходит в админ-системе strapi, и у них на страницу загружались данные уже после загрузки сайта, без редиректов.

Можете пожалуйста написать небольшой пример как это работает? Мне так будет понятнее.

ksa 14.02.2022 21:29

Цитата:

Сообщение от Raadsert
А можете подсказать несколько подобных книг?

Можно начать хоть с этого видоса...
https://www.youtube.com/watch?v=tKM44vPHU0U
А продолжить уже этим
https://www.youtube.com/watch?v=243pQXC5Ebs

На учебники ссылку дать более проблематично и они датируются довольно не свежими годами. Но постараюсь найти...

Цитата:

Сообщение от Raadsert
Мне просто при помощи роутеров создавать заголовок?

Назначение роутеров - обработка запросов.
А вот заголовки приходят как часть самого запроса.

Цитата:

Сообщение от Raadsert
Мне кажется это бессмысленным если речь идёт о передаче в заголовке токена.

Вот посмотри т.с. идеологию ДжиВиТи авторизации
https://www.youtube.com/watch?v=fN25fMQZ2v0
Там будет все. Про токены и заголовки... ;)

ksa 14.02.2022 21:34

Цитата:

Сообщение от Raadsert
А можете подсказать несколько подобных книг?

Вот хорошая серия книг...
https://ru.pdfdrive.com/nodejs-в-д...148600761.html

Или вот такая книжка...
https://ru.pdfdrive.com/front-end-К...e53632633.html

Raadsert 14.02.2022 23:35

Цитата:

Сообщение от ksa (Сообщение 543741)
Можно начать хоть с этого видоса...
https://www.youtube.com/watch?v=tKM44vPHU0U
А продолжить уже этим
https://www.youtube.com/watch?v=243pQXC5Ebs

На учебники ссылку дать более проблематично и они датируются довольно не свежими годами. Но постараюсь найти...


Назначение роутеров - обработка запросов.
А вот заголовки приходят как часть самого запроса.


Вот посмотри т.с. идеологию ДжиВиТи авторизации
https://www.youtube.com/watch?v=fN25fMQZ2v0
Там будет все. Про токены и заголовки... ;)

По поводу последнего видео. Там используют плагин axios, а возможно как то без подобных плагинов обойтись?

ksa 15.02.2022 08:12

Цитата:

Сообщение от Raadsert
а возможно как то без подобных плагинов обойтись?

Пользуйся стандартным fetch...
Главное назначение моих ссылок - довести до тебя идеологию всего этого хозяйства. Ее многогранность.
Чтобы ты "не тыкал палкой в одно место", а мог широко использовать возможности этой клиент-серверной технологии.

Raadsert 18.02.2022 13:42

Цитата:

Сообщение от ksa (Сообщение 543750)
Пользуйся стандартным fetch...
Главное назначение моих ссылок - довести до тебя идеологию всего этого хозяйства. Ее многогранность.
Чтобы ты "не тыкал палкой в одно место", а мог широко использовать возможности этой клиент-серверной технологии.

Большое спасибо за помощь. Уже посмотрел все видео, нечто полезное почерпнул. Сейчас читаю книги. Скажите, а есть какой-то список той информации которую я могу получить от пользователя зашедшего на сайт? (На видео к примеру можно было получить информацию о процессоре)

ksa 18.02.2022 14:12

Цитата:

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

Информацию "о пользователе" может получать клиентский скрипт и серверный...

Серверный скрипт имеет доступ к т.н. req... Это объект запроса.
Там довольно много чего можно узнать "о пользователе"...
Так же есть объект process.
https://nodejsdev.ru/api/process/#uncaughtexception

Полного списка я особо и не искал... :blink:
Если какая-то надобность появлялась - выводил ключи и анализировал "что в них есть".

А что именно "о пользователе" ты хотел узнать?
В учебниках, как правило, рассказывали о некоторых данных и не более того...

Raadsert 18.02.2022 19:21

Цитата:

Сообщение от ksa (Сообщение 543826)
Информацию "о пользователе" может получать клиентский скрипт и серверный...

Серверный скрипт имеет доступ к т.н. req... Это объект запроса.
Там довольно много чего можно узнать "о пользователе"...
Так же есть объект process.
https://nodejsdev.ru/api/process/#uncaughtexception

Полного списка я особо и не искал... :blink:
Если какая-то надобность появлялась - выводил ключи и анализировал "что в них есть".

А что именно "о пользователе" ты хотел узнать?
В учебниках, как правило, рассказывали о некоторых данных и не более того...

Мне кажется серверный получает больше информации о клиенте. В идеале, я хотел бы узнать о всём что там есть, кто знает что может потом пригодиться.

ksa 18.02.2022 21:31

Цитата:

Сообщение от Raadsert
В идеале, я хотел бы узнать о всём что там есть

Тогда после учебников переходи к изучению документации и спецификации http. ;)


Часовой пояс GMT +3, время: 01:55.