Рубрики
Без рубрики

Вход паролем в систему с электронной почтой и JSON WEB Аутентификация токена (JWT) с использованием Next.js

Как вы регистрируете своих пользователей и как вы даете им доступ? Мы перейдем к … Tagged webdev, JavaScript, Учебник.

Как вы регистрируете своих пользователей и как вы даете им доступ? Мы перейдем к аутентификации и авторизации пользователям без паролей в Next.js.

Когда вы начнете добавлять пользователей на свой веб-сайт, главный вопрос, который вам нужно ответить, это: Как вы регистрируете своих пользователей в и как вы даете им доступ к соответствующим ресурсам?

В этом руководстве мы перейдем к тому, как решить как вопросы, и построить приложение Next.js, которое позволяет только зарегистрированными пользователями для доступа к частным ресурсам в приложении.

Таким образом, вы хотите иметь пользователей.

Давайте пройдемся по некоторым понятиям: Аутентификация против авторизации Отказ

Аутентификация: Как я могу войти в систему моих пользователей?

Аутентификация – это способ для вашего сервера для проверки идентификации пользователя. Наиболее распространенным способом аутентификации пользователей является использование комбинации электронной почты/пароля. К сожалению, Пароли имеют серьезные недостатки на взаимодействии как пользовательского интерфейса Отказ В этом руководстве мы будем использовать код подтверждения, отправляемого в электронную почту пользователя для аутентификации пользователя Отказ

Авторизация: Как я могу держать своих пользователей войти в систему?

Авторизация – это способ для вашего сервера для авторизации запроса. В более простых терминах, именно здесь вы проходите в токене или сеансе на ваш бэкфонный сервер при вызове API для просмотра или обновления некоторых данных. 2 общих стратегиях являются Сеансы на основе cookie и JWT жетоны Отказ

Основным преимуществом JWT Tookens является то, что он не сохраняется в вашей базе данных, поэтому вам не нужно делать проверку БД, чтобы проверить каждый запрос. Вот почему Мы собираемся использовать JWT жетоны в этом руководстве.

Узнайте больше о том, как работает OAUTH 2.0 и доступа к токену.

Как будет выглядеть общее регистрация/логин?

Аутентификация: Мы попросим электронной почты пользователя и отправить им письмо, содержащее код. Если пользователь правильно вводит код, мы получим токен JWT в Frontend и храните его в LocalStorage Отказ

Авторизация: Каждый раз, когда мы хотим получить доступ к личной конечной точке API, нам нужно включить заголовок Авторизация: Носитель $ {Токен} Отказ

Хранение токена в браузере локальное хранилище восприимчиво к атаке скриптов с перекрестными сайтами (XSS). Если злоумышленник может успешно запустить код JavaScript на вашем сайте, они могут получить токены, хранящиеся в локальном хранилище. Уязвимость XSS возникает, когда ваш сайт принимает данные от пользователей без надлежащей проверки или из стороннего кода JavaScript (например, Google Analytics, jQuery и т. Д.).

Давайте начнем строить

Создайте свое приложение Next.js. Мы назовем приложение Next-Pancedless-Login и используйте приложение для стартера по умолчанию.

yarn create next-app
cd next-passwordless-login && yarn dev

Обновите наш сайт

Обновите свой Страницы/index.js Отказ Удалить все, кроме стиля и контейнера Div, затем добавьте это внутри контейнера Div.

Passwordless App.

{/* 1️⃣ TODO: Setup a div to contain the form */}

Public Endpoint

You should be able to access this when not logged in

Private Endpoint

You need to log in to access this endpoint

Шаг 1: Покажите форму реестра/входа

Установите зависимости:

yarn add cotter cotter-node

Добавьте div, чтобы содержать форму ниже нашего заголовка в Страницы/index.js.

Passwordless App.

{/* 1️⃣ TODO: Setup a div to contain the form */}

потом Импортируйте и инициализируйте Cotter для встраивания электронной почты.

// 1️⃣ import Cotter verification form and useEffect from react
import Cotter from "cotter";
import { useEffect } from "react";
export default function Home() {
  // 1️⃣ Initialize and show the form
  // Add the lines here
  useEffect(() => {
    var cotter = new Cotter(API_KEY_ID); // 👈 Specify your API KEY ID here
    cotter
      .signInWithOTP()
      .showEmailForm()
      .then(payload => {
        console.log(payload);
        alert("Success");
      })
      .catch(err => console.log(err));

  }, []);
  // until here

  return (...);
}

Вам нужно добавить свой API_KEY_ID здесь. Создать бесплатный аккаунт В Cotter, затем создайте проект и делать заметки ключей API.

Теперь вы должны быть в состоянии увидеть форму входа в систему, как ниже.

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

Шаг 2: Держите пользователю войти в систему с Access_Token

Прочитайте Console.log

Попробуйте ввести свой адрес электронной почты и вход в систему. Вы должны увидеть, что полезная нагрузка Мы получаем в OnSuccess Функция содержит следующий объект:

{
  "token": {...},
  "email": "team@cotter.app",
  "oauth_token": {
    "access_token": "eyJhbGciOiJFUzI1NiIsIn...",
    "id_token": "eyJhbGciOiJFUzI1NiIsInR5cC...",
    "refresh_token": "199:doZor3GtgsrYo4R7L...",
    "expires_in": 3600,
    "token_type": "Bearer",
    "auth_method": "OTP"
  },
  "user": {
    "ID": "ecadbd2c-56f8-4078-b45d-f17786ed499e", // Cotter User ID
    ...
  }
}

Мы хотим использовать Access_Token В этом руководстве, так что давайте схватим это и храним его в LocalStorage Отказ

    useEffect(() => {
    var cotter = new Cotter(API_KEY_ID); // 👈 Specify your API KEY ID here
    cotter
      .signInWithOTP()
      .showEmailForm()
      .then(payload => {
        console.log(payload);
-        alert("Success");

+        // 2️⃣(a) Store the access token and set logged in
+        localStorage.setItem("ACCESS_TOKEN", payload.oauth_token.access_token);
+        setIsLoggedIn(true);
      })
      .catch(err => console.log(err));
  }, []);

Теперь давайте определим setislogedin () , это поможет нам показать, вошел ли пользователь в системе или нет.

     import Cotter from "cotter";
     import { useEffect } from "react";
+    import { useState } from "react";

    export default function Home() {
+      // 2️⃣(a) Show if the user is logged in.
+      var [isLoggedIn, setIsLoggedIn] = useState(false);

Мы также хотим проверить, если LocalStorage Содержит Access_Token Каждый раз, когда страница загружает и обновляется наш isloggedin Переменная. Добавьте это ниже первого Useffect () Отказ

// 1️⃣ Initialize and show the form
useEffect(() => {...}, []);

// Add the lines below here
// 2️⃣(b) Check if the ACCESS_TOKEN exists every time the page loads
useEffect(() => {
    if (localStorage.getItem("ACCESS_TOKEN") != null) {
        setIsLoggedIn(true);
    }
}, []);

Теперь давайте покажем, если пользователь вошел в систему ниже нашей формы:

{/* 2️⃣(c) Show if the user is logged in. */}

{isLoggedIn ? "✅ You are logged in" : "❌ You are not logged in"}

Шаг 3: Регистрация

Регистрация достигается путем удаления Access_Token от нашего LocalStorage Отказ Давайте добавим функцию выхода из системы внутри Главная до return () в страницы/index.js.

// 3️⃣ Log out users
const logOut = () => {
    localStorage.removeItem("ACCESS_TOKEN");
    setIsLoggedIn(false);
};

И показать кнопку выхода:

{/* 3️⃣ Show the logout button */}
{isLoggedIn ? (
    
Log Out
) : null}

Теперь вы можете увидеть, как вы вошли в систему, и кнопка «Выход»:

Шаг 4: позволяя пользователю доступа к публичным/частным конечным точкам.

Давайте добавим 2 пути в нашу страницы/API.

touch pages/api/public.js pages/api/private.js

Определение маршрутов

Давайте определим нашу /API/Public Конечная точка в Страницы/API/public.js Отказ Мы просто собираемся вернуть, что запрос успешен.

export default (req, res) => {
  res.statusCode = 200;
  res.end(
    "Success! This is a public resource, you can see it without logging in."
  );
};

Давайте определим нашу /API/Private Конечная точка в Страницы/API/Private.js . Сначала мы проверим, существует ли заголовок авторизации.

// 2) TODO: Import Cotter

const checkJWT = (handler) => async (req, res) => {
  // 1) Check that the access_token exists
  if (!("authorization" in req.headers)) {
    res.statusCode = 401;
    res.end("Authorization header missing");
  }
  const auth = await req.headers.authorization;
  const bearer = auth.split(" ");
  const token = bearer[1];
  console.log(token);

  // 2) TODO: Validate the access_token

  handler(req, res);
}

const handler = (req, res) => {
  res.statusCode = 200;
  res.end(
    `Success! This is a private resource and you have the access_token to view it.`
  );
};

export default checkJWT(handler);

Теперь давайте проверим токен доступа.

Во-первых, импортировать функцию валидатора JWT Chotter в верхней части Страницы/API/Private.js

import { CotterValidateJWT } from "cotter-node";

Тогда звоните Cottervalidatejwt (токен) под шагом (2) внутри CheckJWT Отказ

  // 2) TODO: Validate the access_token
  var valid = false;
  try {
    valid = await CotterValidateJWT(token);
  } catch (e) {
    console.log(e);
    valid = false;
  }
  if (!valid) {
    res.statusCode = 403;
    res.end("Authorization header is invalid");
  }

Вызов/общедоступные и/частные API конечные точки API

Давайте вернемся к Страницы/index.js и добавьте 2 функции: getpublicresource а также GetPrivAresource Это позвонит конечной точке /API/общественность и /API/Private Отказ

export default function Home() {
  ...

  // 4️⃣ Get Public and Private Resources
  // Add the lines here
  var [publicResource, setPublicResource] = useState(null);
  var [privateResource, setPrivateResource] = useState(null);

  // Get Public Resource
  const getPublicResource = async () => {
    var resp = await fetch("/api/public");
    setPublicResource(await resp.text());
  };

  // Get Private Resource
  const getPrivateResource = async () => {
    var token = localStorage.getItem("ACCESS_TOKEN");
    if (token == null) {
      setPrivateResource("Token doesn't exist, you're logged-out");
      return;
    }
    var resp = await fetch("/api/private", {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });
    setPrivateResource(await resp.text());
  };
  // Until here

  return(...);
}

Теперь давайте назовем 2 функции с наших кнопок и показать ответ с конечных точек. Обновите Div с ClassName = "Сетка" в следующий код:

{/* 4️⃣ Call Get Public and Private Resources */}

Public Endpoint

{publicResource}

Private Endpoint

{privateResource}

Мы отображаем ответ с конечных точек в PublicSource и Приварьсурс Переменные.

Вот и все

Теперь вы можете аутентифицировать пользователей, отправив код на их электронные письма и позвольте им получить доступ к частным конечным точкам, которые требуют Access_Token к доступу.

Если вам интересно, распечатайте Access_Token и скопируйте это на https://jwt.io/ Чтобы увидеть, какая информация декодирована. id_token Содержит дополнительную информацию о пользователе и Refresh_token используется для получить новый Access_Token Если это истекло .

Что дальше?

Узнайте больше о Оатские токены, возвращенные из Cotter И используйте их в конечных точках вашего API.

Если вы хотите аутентифицировать пользователей, используя свой номер телефона, следуйте этому руководству на Проверка телефона пользователя через SMS и WhatsApp Отказ

Вопросы и обратная связь.

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь присоединиться к Cotter’s Slack Channel И поговорите с нами там.

Готов к использованию Cotter?

Если вам понравилось этот учебник и хотите интегрировать Cotter на свой веб-сайт или приложение, вы можете Создать бесплатный аккаунт и Проверьте нашу документацию Отказ

Оригинал: “https://dev.to/cotter/passwordless-login-with-email-and-json-web-token-jwt-authentication-using-next-js-539o”