Авторизация, third party cookie, Bearer token

10.05.2024 в 10:27



Проблема с авторизацией? Надеемся, здесь ты найдёшь ответы на все вопросы. Мы точно проанализируем ваши вопросы в комментах именно в этой статье (только те вопросы, которые касаются аутентификации\авторизации) и добавим недостающие рецепты в статью.

😔 Проблема с авторизацией? Надеемся, здесь ты найдёшь ответы на все вопросы. Мы точно проанализируем ваши вопросы в комментах именно в этой статье (только те вопросы, которые касаются аутентификации\авторизации) и добавим недостающие рецепты в статью. Если у тебя всё работает так, как в видео, не усложняй пока что себе жизнь и иди точь-в-точь по видео. 

Бигтех и правительства между собой договариваются, каким именно образом и кто будет иметь право моноплизировать слежку за нами через cookie и другим способом. Но нам интересуют сейчас именно Cookie, потому что определённые ограничения мешают вам, обучающимся новичкам, спокойно обучаться.

Например Google Chrome обещает (обещал) до конца года полностью выключить third party cookie, это значит что условно с вашего my-samurai.github.com кука для social-network.samuraijs.com не полетит и авторизация, основанная на кросдоменной куке отвалится полностью. Вроде как из-за этого пострадают большие маркетинговые и рекламные компании (миллиарды денег), поэтому этот процесс возможно затянется более чем до конца этого года. Но Хром уже для 1% пользователей активирует эту фичу, а значит у 1 из 100 пользователей нашей апишки не будет работать cookie-авторизация и помочь вам в этом никто не сможет.

Поэтому мы нашли время и немного доработали нашу апишку.

 

🙌🏻 Оплата API

Апи вот уже 2 года работает без оплаты как подарок миру! Если у вас есть возможность отблагодарить нас, пожалуйста, оформите подписку на youtube, patreon или boosty

🍪 Можно полностью отказаться от Cookie

🟢 Пример 1: мы не умеем логиниться из приложения 

В этом видео 61 - React JS - cookie, login в теории, auth/me вот прям с момента определённого мы хотим сделать авторизованный запрос, чтобы сервер понял, что я это я.

❌ Раньше было вот так (с расчётом на куку) (для многих это будет работать и дальше):

  1. Я на этом сайте, где сейчас читаю эту статью, логинился
  2. Шёл в своё приложение, выставлял там withCredentials: true
  3. Браузер цеплял автоматом куку и отправлял таким образом из моего SPA-приложения авторизованный запрос на API

✅ Сейчас можно будет забить на withCredentials (эта опция именно про куку) и положиться на ваш личный токен:

  1. Иду на страницу настроек и копирем токен (см. скрин) Ах да, этот токен в отличие от API-KEY держим в секрете, потому что буквально это ваш паспорт, который нельзя потерять
  2. Дальше делая запрос в axios при запросе в объекте конфигурации вместо свойства withCredentials добавляем свойство headers, которое в свою очередь является объектом, в котором есть ещё одно свойство "Authorization" со значением "Bearer" + " " + скопированный_токен.  То есть слово Bearer + ПРОБЕЛ + ТОКЕН.
    Для примера из скиншота это будет выглядеть так (токен вставляйте свой):

    axios.get('https://social-network.samuraijs.com/api/1.0/auth/me', {
        withCredentials: true
        headers: {
            "Authorization": "Bearer 8bdba674-1a3d-4ea5-a543-f143be76efbd
    "
        }

    })
    .then(response => {
        debugger;
    });
  3. На этом всё - теперь вместо куки полетит токен. Можете называть его Access Token, аналогичный JWT токену, только живёт этот токен вечно. Пока вы не перелогинетесь заново и  этот токен не будет перегенерирован.
  4. ВНИМАНИЕ! Не отправляйте этот токен в GIT репозиторий, соответственно и на хостинги

 

🟢 Как добавить token к кажому запросу?

Вот здесь 63 - React JS - практика, DAL, axios.create мы создавали instance для axios  с общими настройками для всех запросов, сделанных через этот instance.

const instance = axios.create({
     withCredentials: true,
     headers: {
              "API-KEY": "b1775b2f-c3a5-4509-8dc9-90b5629de7c3",
              "Authorization": "Bearer 8bdba674-1a3d-4ea5-a543-f143be76efbd"
          }
     });

⚠ Внимание: не коммитьте этот код в репозиторий

🟢 Пример 2: логинимся через наше SPA-приложение через самописную форму логина

Друзья, когда мы хотим автоматизировать процесс логина как вот здесь 78 - React JS - login и logout api до текущего момента делаем всё тоже самое, но после - немного иначе, потому что мы не можем полагаться на куку и нам нужно где-то взять актуальный токен и цеплять его к каждому запросу с помощью кода.

  1. В момент /auth/login через API как на видео при удачном логине нам сервер вернёт в ответе ещё и токен (он будет совпадать с тем, который в предыдущем примере мы брали с вами на странице аккуанта на сайте)

    export const login = (email, password, rememberMe) => (dispatch) => {
         authAPI.login(email, password, rememberMe)
               .then(response => {
                    if (response.data.resultCode === 0) {
                         // достаём из ответа ещё и токен
                         let {id, login, email, token} = response.data.data;
                         // сохраняем это токен в localStorage (погуглите, что это)
                         localStorage.setItem("sn-token", token);
                         dispatch(setAuthUserData(id, email, login));
                    }
                 });
    }; 
  2. Имея в localStorage данный токен, мы можем прочитать из него данный код в любом месте и прикрепить к каждому запросу через axios interceptor (ниже детали). 

🟢 Как добавить token к кажому запросу после логина?

Вот здесь 63 - React JS - практика, DAL, axios.create мы создавали instance для axios  с общими настройками. 

const instance = axios.create({
     withCredentials: true,
     headers: {
              "API-KEY": "b1775b2f-c3a5-4509-8dc9-90b5629de7c3"
          }
     });

Мы не можем здесь указать наш токен, так как заранее (до момента логина) он нам не известен. Поэтому мы донастроим наш instance, чтобы он перехватывал каждый запрос и добавлял к нему наш токен, который мы положили ранее в localStorage:

const instance = axios.create({
     withCredentials: true,
     headers: {
              "API-KEY": "b1775b2f-c3a5-4509-8dc9-90b5629de7c3"
          }
     });

instance.interceptors.request.use(function (config) {
   config.headers["Authorization"] = "Bearer " + localStorage.getItem("sn-token");

   return config;
});

Данный interceptor будет перехватывать все запросы и добавлять в headers заголовок Authorization с вашим токеном, который перехватчик достанет из localStorage

 

😁 Что может пойти не так?

👴🏻 Вы забыли явно залогиниться через форму

Если вы для примера 2 явно не залогинились, то в localStorage у вас будет пусто и интерсептор прочитает пустоту (undefined) и отправит в качестве токена "ничего". А токен должен быть валидным

⏳ Токен протух

Если вы идёте по примеру 1, вы залогинились на сайте, руками скопировали токен и вставили его в код, всё работает.
Но потом вы через другой браузер или с мобильноо устройства или в этом же браузере вылогинились и залогинились ещё раз, то ваш токен, который вы скопировали ранее в своё приложение будет считаться протухшим (expired) и нужно на странице настроек скопировать новый токен.

 

 

Ваши кейсы из комментариев

-----

0
541
С этой статьёй так же читают

Комментарии (0):

0 17.05.2024 в 07:37
Привет! Немного непонятен вопрос безопасности. В первом примере - мы никуда не коммитим, чтобы его не было в открытом доступе, при этом во втором примере он хранится в localStorage, куда каждый может зайти и посмотреть.
0 28.05.2024 в 05:20
doroshkent, localStorage - это хранилище в твоем браузере. Т.е. единственный вариант как я могу украсть у тебя токен - это узнать твой домашний адрес, пробраться к тебе домой, открыть твой комп, зайти на https://social-network.samuraijs.com/ и записать значение токена )
0 12.06.2024 в 04:15
Но отчасти ты прав. Существуют XSS (Cross-Site Scripting) атаки и это уязвимость
Чтобы оставить отзыв, войдите на сайт