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

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

Это привело к росту популярности одноразового пароля (OTP), когда сгенерированный пароль действителен только для одного сеанса входа в систему. Как сделать его безопасным и масштабируемым? Как мы можем использовать AWS для создания и встраивания OTP в наши приложения? В этом проекте давайте исследуем AWS и реализуем OTP-аутентификацию с помощью ReactJS и AWS Amplify.

Что такое AWS Amplify

AWS Amplify - это платформа разработки для создания безопасных, масштабируемых мобильных и веб-приложений. Он скрывает фактические детали реализации, необходимые для выполнения в AWS, обеспечивая при этом хорошее взаимодействие с разработчиками, которое вы ожидали от своего любимого терминала.

Он охватывает весь рабочий процесс разработки мобильных приложений от контроля версий, тестирования кода до производственного развертывания и легко масштабируется вместе с вашим бизнесом от тысяч пользователей до десятков миллионов. Библиотеки Amplify и CLI, являющиеся частью Amplify Framework, имеют открытый исходный код и предлагают подключаемый интерфейс, который позволяет настраивать и создавать свои собственные подключаемые модули.

Создать приложение React

Давайте начнем с нового приложения React через create-react-app, и вам понадобится как минимум node ›= 8.10 на вашей локальной машине разработки. В настоящее время я использую узел v13.14.0 (npm v6.14.4)

create-react-app amplify-react-otp --template typescript

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

cd amplify-react-otp

Хорошо, теперь мы готовы запачкать руки.

AWS Amplify - это платформа разработки для создания безопасных масштабируемых мобильных и веб-приложений.

Добавление библиотек пользовательского интерфейса

Это совершенно необязательно. В этом проекте мы собираемся использовать библиотеку пользовательского интерфейса Bootstrap с react-bootstrap, чтобы наше приложение React выглядело немного лучше.

yarn add react-bootstrap bootstrap

Добавление некоторых компонентов React

С домашней страницы React JS по умолчанию я добавлю некоторые компоненты пользовательского интерфейса для работы с ними позже. Новое приложение React поставляется с некоторыми базовыми стилями CSS, и мы собираемся повторно использовать некоторые из них в этом руководстве. Вот компоненты, которые я добавляю:

  • Форма ввода для ввода номера телефона
  • Форма ввода для ввода одноразового пароля
  • Кнопка выхода
  • Кнопка, чтобы проверить, вошел ли я в систему (необязательно)

Коды javascript для рендеринга пользовательского интерфейса теперь будут выглядеть следующим образом.

<div className='App'>
  <header className='App-header'>
    <img src={logo} className='App-logo' alt='logo' />
    <p>Some message here</p>
    <div>
      <InputGroup className='mb-3'>
        <FormControl
          placeholder='Phone Number (+XX)'
        />
        <InputGroup.Append>
          <Button variant='outline-secondary'>Get OTP</Button>
        </InputGroup.Append>
      </InputGroup>
    </div>
    <div>
      <InputGroup className='mb-3'>
        <FormControl
          placeholder='Your OTP'
        />
        <InputGroup.Append>
          <Button variant='outline-secondary'>Confirm</Button>
        </InputGroup.Append>
      </InputGroup>
    </div>
    <div>
      <ButtonGroup>
        <Button variant='outline-primary'>Am I sign in?</Button>
        <Button variant='outline-danger'>Sign Out</Button>
      </ButtonGroup>
    </div>
  </header>
</div>

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

yarn start

Добавление строительных блоков

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

const signOut = () => {};
const signIn = () => {};
const verifyOtp = () => {};
const verifyAuth = () => {};

Обратите внимание, что у нас нет функции signUp, и это потому, что мы можем обрабатывать эту часть логики с помощью функции signIn. Позже мы можем немного почистить код, если функции станут беспорядочными. Теперь давайте свяжем функцию с каждой кнопкой, выделенной в функции render. Теперь ваши коды javascript должны выглядеть следующим образом.

function App() {
  const signOut = () => {};
  const signIn = () => {};
  const verifyOtp = () => {};
  const verifyAuth = () => {};
  return (
    <div className='App'>
      <header className='App-header'>
        <img src={logo} className='App-logo' alt='logo' />
        <p>Some message here</p>
        <div>
          <InputGroup className='mb-3'>
            <FormControl placeholder='Phone Number (+XX)' />
            <InputGroup.Append>
              <Button variant='outline-secondary' onClick={signIn}>
                Get OTP
              </Button>
            </InputGroup.Append>
          </InputGroup>
        </div>
        <div>
          <InputGroup className='mb-3'>
            <FormControl placeholder='Your OTP' />
            <InputGroup.Append>
              <Button variant='outline-secondary'
                  onClick={verifyOtp}>
                Confirm
              </Button>
            </InputGroup.Append>
          </InputGroup>
        </div>
        <div>
          <ButtonGroup>
            <Button variant='outline-primary' onClick={verifyAuth}>
              Am I sign in?
            </Button>
            <Button variant='outline-danger' onClick={signOut}>
              Sign Out
            </Button>
          </ButtonGroup>
        </div>
      </header>
    </div>
  );
}

Аутентификация и авторизация с помощью AWS Amplify

Прежде чем мы углубимся в AWS Amplify и настроим его auth компонент, мы должны сначала понять, как работает Amazon Cognito.

Возможности и безопасность

Amazon Cognito служит управляемой службой аутентификации, которая предоставляет возможности аутентификации и авторизации пользователей для управления доступом к вашим веб-приложениям и мобильным приложениям. У вас также есть доступ к функциям Advanced Security, которые включают адаптивную аутентификацию на основе рисков и защиту от скомпрометированных учетных данных.

Управление пользователями

Amazon Cognito предоставляет вам возможность лучше управлять своими пользователями с помощью Пользовательских групп и Пользовательских лямбда-триггеров, которые можно активировать во время аутентификации пула пользователей, например регистрации пользователей, подтверждение и пост-подтверждение. Мы собираемся изучить эти триггеры в Amplify CLI, чтобы настроить способ аутентификации пользователей.

Настраиваемый процесс аутентификации

Современные потоки аутентификации включают новые типы запросов, такие как Captcha и OTP, для проверки личности пользователя поверх существующего верификатора пароля. Amazon Cognito предоставляет возможность настроить процесс аутентификации с помощью триггеров AWS Lambda.

Давайте теперь посмотрим на процесс аутентификации, который нам нужно настроить в этом проекте.

По умолчанию вновь созданный пользователь имеет статус unconfirmed в пуле пользователей Cognito, и пользователь может подтвердить свою учетную запись по электронной почте или по номеру телефона. Поскольку мы также используем OTP для аутентификации пользователей, нам не нужно подтверждать и проверять номер телефона (снова). Чтобы автоматически подтверждать пользователя в процессе регистрации, нам необходимо обновить статус пользователя на этапе pre sign-up во время аутентификации пула пользователей. В целом, чтобы завершить весь процесс аутентификации для этого проекта, нам нужно добавить и обновить следующие 4 лямбда-триггера Cognito.

Проверьте версию своего узла

Прежде чем мы начнем усилить -ing, вы должны убедиться, что используете как минимум версию узла 10 и выше. Вы можете ввести следующую команду, чтобы проверить версию вашего узла.

node -v

Если вы понимаете, что используете не последнюю версию node / npm, вы можете использовать Диспетчер версий узла (NVM) для установки и выбора нужной вам версии узла. Вы можете ввести следующую команду, чтобы установить и использовать версию узла 13.

nvm install 13 && nvm use 13

Время усилить

Amplify Command Line Interface (CLI) - это унифицированный набор инструментов для создания облачных сервисов AWS для вашего приложения. Давайте продолжим и установим Amplify CLI.

yarn global add @aws-amplify/cli

Теперь мы можем приступить к инициализации нашего нового проекта Amplify в папке приложения React. Это должно запустить новый стек Amazon CloudFormation в нашей среде AWS.

amplify init

Добавить аутентификацию через Amplify CLI

Вернемся к нашей основной повестке дня - использовать AWS Amplify для предоставления функций Auth в AWS. Amplify CLI поддерживает настройку множества различных рабочих процессов аутентификации и авторизации, включая простые и расширенные конфигурации параметров входа в систему, запуск функций Lambda во время различных событий жизненного цикла и административные действия, которые вы можете дополнительно предоставить своим приложениям. И именно поэтому нам фактически не нужно возвращаться в консоль AWS, чтобы щелкнуть и настроить вручную в браузере. Теперь давайте добавим auth функций, выбрав Manual Configuration.

amplify add auth

Теперь мы дадим понятное имя нашим ресурсам AWS, пулу пользователей и пулу удостоверений, чтобы (если у вас несколько проектов) мы могли легко найти их в будущем. В этом проекте я назвал свои ресурсы amplifyreactotp.

На что следует обратить внимание

  1. В разделе What attributes are required for signing up? вы должны выбрать Phone Number и отменить выбор Email, поскольку мы собираемся использовать номер телефона только для аутентификации пользователя. ВАЖНО. Обратите внимание, что вы не можете изменить это требование атрибута для процесса регистрации в будущем. Если вам все же нужно что-то изменить, заново сконфигурируйте auth компоненты с самого начала.
  2. В разделе Do you want to specify the user attributes this app can read and write? вам также необходимо выбрать Phone Number для чтения и записи.
  3. В разделе Do you want to enable any of the following capabilities? вам нужно выбрать Custom Auth Challenge Flow (basic scaffolding - not for production), и мы собираемся обновить код, чтобы аутентификация OTP работала для производственного использования.
  4. Под Which triggers do you want to enable for Cognito вы увидите, что 3 лямбда-триггера автоматически выбираются для настраиваемого потока аутентификации. Теперь вам нужно также выбрать опциюPre Sign-up.

Добавление лямбда-триггеров

После того, как вы выполнили настройку amplify add auth, вам нужно будет обновить 4 функции. Во-первых, давайте рассмотрим код javascript для create-challenge лямбда-триггера. Вы также должны принять во внимание, что в этой функции мы собираемся выполнить несколько ключевых шагов, чтобы убедиться, что этот процесс OTP работает:

  1. Сгенерировать 6 случайных чисел как одноразовый пароль
  2. Чтобы использовать SNS для отправки SMS с OTP
  3. Передайте значение OTP в качестве ответа обратно в Amazon Cognito для проверки.
const AWS = require('aws-sdk');
exports.handler = (event, context, callback) => {
  //Create a random number for otp
  const challengeAnswer = Math.random().toString(10).substr(2, 6);
  const phoneNumber = event.request.userAttributes.phone_number;
  //sns sms
  const sns = new AWS.SNS({ region: 'us-east-1' });
  sns.publish(
    {
      Message: 'your otp: ' + challengeAnswer,
      PhoneNumber: phoneNumber,
      MessageStructure: 'string',
      MessageAttributes: {
        'AWS.SNS.SMS.SenderID': {
          DataType: 'String',
          StringValue: 'AMPLIFY',
        },
        'AWS.SNS.SMS.SMSType': {
          DataType: 'String',
          StringValue: 'Transactional',
        },
      },
    },
    function (err, data) {
      if (err) {
        console.log(err.stack);
        console.log(data);
        return;
      }
      return data;
    }
  );
  //set return params
  event.response.privateChallengeParameters = {};
  event.response.privateChallengeParameters.answer = challengeAnswer;
  event.response.challengeMetadata = 'CUSTOM_CHALLENGE';
  callback(null, event);
};

Поскольку нам нужна возможность отправлять OTP через SMS, мы будем использовать Amazon Simple Notification Service (SNS) для отправки SMS. По умолчанию лямбда-функция не имеет разрешения на использование SNS, поскольку, согласно передовому опыту, функция предоставляется только с наименее привилегированными правами через AWS Identity and Access Management (IAM). Следовательно, нам нужно будет обновить файл CloudFormation json, расположенный в папке amplify, которая автоматически создается файлом amplify-cli.

Под lambdaexecutionpolicy вы можете вставить следующее (как показано выше), чтобы добавить разрешение на отправку SMS через SNS.

{
  "Sid": "VisualEditor1",
  "Effect": "Allow",
  "Action": "sns:Publish",
  "Resource": "*"
}

Переходя к следующей функции, вы можете обновить функцию define challenge на следующие коды javascript. Мы собираемся ограничить количество способов только аутентификации и использования CUSTOM_CHALLENGE, которые информируют Amazon Cognito о переходе к функцииcreate-challenge.

exports.handler = (event, context) => {
  if (event.request.session.length === 0) {
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = 'CUSTOM_CHALLENGE';
  } else if (
    event.request.session.length === 1 &&
    event.request.session[0].challengeName === 'CUSTOM_CHALLENGE' &&
    event.request.session[0].challengeResult === true
  ) {
    event.response.issueTokens = true;
    event.response.failAuthentication = false;
  } else {
    event.response.issueTokens = false;
    event.response.failAuthentication = true;
  }
  context.done(null, event);
};

Затем мы можем обновить код для функции pre sign-up. Вы можете видеть, что в коде мы также автоматически проверили адрес электронной почты и номер телефона, если они указаны в запросе. В основном это делается для повторного использования, и вы можете использовать и настраивать этот код в соответствии с вашими потребностями в будущем. В этом проекте состояние электронной почты не имеет значения.

exports.handler = (event, context, callback) => {
  // Confirm the user
  event.response.autoConfirmUser = true;
  // Set the email as verified if it is in the request
  if (event.request.userAttributes.hasOwnProperty('email')) {
    event.response.autoVerifyEmail = true;
  }
  // Set the phone number as verified if it is in the request
  if (event.request.userAttributes.hasOwnProperty('phone_number')) {
    event.response.autoVerifyPhone = true;
  }
  // Return to Amazon Cognito
  callback(null, event);
};

И, наконец, это коды для функции verify.

exports.handler = (event, context) => {
  if (event.request.privateChallengeParameters.answer === event.request.challengeAnswer) {
    event.response.answerCorrect = true;
  } else {
    event.response.answerCorrect = false;
  }
  context.done(null, event);
};

Наконец, давайте проверим, правильно ли мы добавили auth и function, введя следующую команду и, как показано на скриншоте ниже, мы должны увидеть все новые четыре функции и ресурсы аутентификации.

amplify status

А теперь давайте внесем изменения в AWS, и пусть ampify творит свое волшебство.

amplify push

Добавьте AWS Amplify в свое приложение React

Нам понадобятся две библиотеки npm от @ aws-ampify для configure и добавления auth в приложение React.

yarn add @aws-amplify/core @aws-amplify/auth

После добавления пакетов мы можем перейти к App.tsx, чтобы начать с импорта и добавления следующего в начало файла.

import Amplify from '@aws-amplify/core';
import Auth from '@aws-amplify/auth';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);

Добавление некоторых констант и переменных

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

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

const NOTSIGNIN = 'You are NOT logged in';
const SIGNEDIN = 'You have logged in successfully';
const SIGNEDOUT = 'You have logged out successfully';
const WAITINGFOROTP = 'Enter OTP number';
const VERIFYNUMBER = 'Verifying number (Country code +XX needed)';

Затем мы обновим следующие четыре функции, чтобы начать использовать возможности ampify auth.

const signOut = () => {};
const signIn = () => {};
const verifyOtp = () => {};
const verifyAuth = () => {};

Нам также потребуется захватить вводимые пользователем данные для number в качестве номера телефона пользователя и otp для значения OTP, необходимого для проверки запроса.

<FormControl
  placeholder='Phone Number (+XX)'
  onChange={(event) => setNumber(event.target.value)}
/>
<FormControl
  placeholder='Your OTP'
  onChange={(event) => setOtp(event.target.value)}
  value={otp}
/>

Добавление функций аутентификации в приложение React

Давайте посмотрим на функцию signIn ниже. Мы будем использовать код исключения, чтобы определить, существует ли пользователь в пуле пользователей Cognito или нет. Если он существует, он вызовет create-challenge лямбда-триггер, и мы сможем получить одноразовый пароль.

const signIn = () => {
  Auth.signIn(number)
    .then((result) => {
      // OTP TRIGGERED
    })
    .catch((e) => {
      if (e.code === 'UserNotFoundException') {
        // SIGN UP HERE
      } else if (e.code === 'UsernameExistsException') {
        // SIGN IN HERE
      } else {
        // SOMETHING IS WRONG
      }
    });
};

Для лучшего UX вы можете установить другое сообщение при нажатии кнопки «Войти» и показывать другое сообщение при отправке OTP SMS. Таким образом, с точки зрения пользователя, приложение React «работает в процессе», пока мы ждем, пока Cognito запустит лямбда-функции. Чтобы выполнить функцию signIn, вы можете обновить код до следующего.

const signIn = () => {
  setMessage(VERIFYNUMBER);
  Auth.signIn(number)
    .then((result) => {
      setSession(result); // Note that this is a new variable
      setMessage(WAITINGFOROTP);
    })
    .catch((e) => {
      if (e.code === 'UserNotFoundException') {
        signUp(); // Note that this is a new function to be created later
      } else if (e.code === 'UsernameExistsException') {
        setMessage(WAITINGFOROTP);
        signIn();
      } else {
        console.log(e.code);
        console.error(e);
      }
    });
};

В этом случае, поскольку новый signUp процесс является асинхронным, мы будем await для завершения signUp процесса, прежде чем снова signIn.

const signUp = async () => {
  const result = await Auth.signUp({
    username: number,
    password,
    attributes: {
      phone_number: number,
    },
  }).then(() => signIn()); // After signUp, we are going to signIn() 
  return result;
};

Теперь давайте посмотрим на функцию verifyOtp. Вы заметили новую переменную session в предыдущем коде? Нам нужно будет передать переменную session в signIn функцию раньше? Как только OTP будет проверен и запрос будет принят, вы сможете получить пользователя useras Cognito (как показано ниже).

const verifyOtp = () => {
  Auth.sendCustomChallengeAnswer(session, otp)
    .then((user) => {
      setUser(user); // this is THE cognito user 
      setMessage(SIGNEDIN);
      setSession(null);
    })
    .catch((err) => {
      setMessage(err.message);
      setOtp('');
      console.log(err);
    });
};

Похоже, мы более-менее закончили. Давайте реализуем функцию signOut. Знаете ли вы, что вы также можете инициировать signOut глобально, если хотите, чтобы текущий пользователь вышел из всех своих существующих сеансов в других браузерах? Мы очистим или null значения для переменных, так как мы можем использовать их, чтобы указать компоненты пользовательского интерфейса, должны ли они отображаться или скрываться.

const signOut = () => {
  if (user) {
    Auth.signOut();
    setUser(null);
    setOtp('');
    setMessage(SIGNEDOUT);
  } else {
    setMessage(NOTSIGNIN);
  }
};

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

useEffect(() => {
  verifyAuth()
}, []);
const verifyAuth = () => {
  Auth.currentAuthenticatedUser()
    .then((user) => {
      setUser(user);
      setMessage(SIGNEDIN);
      setSession(null);
    })
    .catch((err) => {
      console.error(err);
      setMessage(NOTSIGNIN);
    });
};

Задайте условия для компонентов пользовательского интерфейса

Здесь мы можем кое-что сделать, чтобы пользователь знал, на чем он должен сосредоточить свое внимание. Например, мы будем показывать форму ввода OTP только тогда, когда пользователь ввел свой номер телефона и нажал кнопку «Войти». Если вы заметили, что мы ранее объявили несколько переменных для работы, нам нужно будет поставить условия с несколькими переменными для хранения определенных значений, когда мы скрываем и показываем определенные элементы пользовательского интерфейса.

{{ condition && (
      <div>your UI element</div>
   )
}}

Когда пользователь не вошел в систему и не пытался войти, вы можете использовать это условие !user && !session. И когда пользователь не вошел в систему и не пытается войти, мы можем использовать следующее условие !user && session.

Библиотека Amplify упрощает интеграцию кода с серверной частью с помощью декларативных интерфейсов и простых компонентов пользовательского интерфейса.

Все приложение React

Хорошо, давайте взглянем на все приложение React в App.tsx. Вы можете найти исходный код из моего репозитория Github.

import React, { useState, useEffect } from 'react';
import logo from './logo.svg';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import Button from 'react-bootstrap/Button';
import ButtonGroup from 'react-bootstrap/ButtonGroup';
import InputGroup from 'react-bootstrap/InputGroup';
import FormControl from 'react-bootstrap/FormControl';
import Amplify from '@aws-amplify/core';
import Auth from '@aws-amplify/auth';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
const NOTSIGNIN = 'You are NOT logged in';
const SIGNEDIN = 'You have logged in successfully';
const SIGNEDOUT = 'You have logged out successfully';
const WAITINGFOROTP = 'Enter OTP number';
const VERIFYNUMBER = 'Verifying number (Country code +XX needed)';
function App() {
  const [message, setMessage] = useState('Welcome to Demo');
  const [user, setUser] = useState(null);
  const [session, setSession] = useState(null);
  const [otp, setOtp] = useState('');
  const [number, setNumber] = useState('');
  const password = Math.random().toString(10) + 'Abc#';
  useEffect(() => {
    verifyAuth();
  }, []);
  const verifyAuth = () => {
    Auth.currentAuthenticatedUser()
      .then((user) => {
        setUser(user);
        setMessage(SIGNEDIN);
        setSession(null);
      })
      .catch((err) => {
        console.error(err);
        setMessage(NOTSIGNIN);
      });
  };
  const signOut = () => {
    if (user) {
      Auth.signOut();
      setUser(null);
      setOtp('');
      setMessage(SIGNEDOUT);
    } else {
      setMessage(NOTSIGNIN);
    }
  };
  const signIn = () => {
    setMessage(VERIFYNUMBER);
    Auth.signIn(number)
      .then((result) => {
        setSession(result);
        setMessage(WAITINGFOROTP);
      })
      .catch((e) => {
        if (e.code === 'UserNotFoundException') {
          signUp();
        } else if (e.code === 'UsernameExistsException') {
          setMessage(WAITINGFOROTP);
          signIn();
        } else {
          console.log(e.code);
          console.error(e);
        }
      });
  };
  const signUp = async () => {
    const result = await Auth.signUp({
      username: number,
      password,
      attributes: {
        phone_number: number,
      },
    }).then(() => signIn());
    return result;
  };
  const verifyOtp = () => {
    Auth.sendCustomChallengeAnswer(session, otp)
      .then((user) => {
        setUser(user);
        setMessage(SIGNEDIN);
        setSession(null);
      })
      .catch((err) => {
        setMessage(err.message);
        setOtp('');
        console.log(err);
      });
  };
  return (
    <div className='App'>
      <header className='App-header'>
        <img src={logo} className='App-logo' alt='logo' />
        <p>{message}</p>
        {!user && !session && (
          <div>
            <InputGroup className='mb-3'>
              <FormControl
                placeholder='Phone Number (+XX)'
                onChange={(event) => setNumber(event.target.value)}
              />
              <InputGroup.Append>
                <Button variant='outline-secondary'
                     onClick={signIn}>
                  Get OTP
                </Button>
              </InputGroup.Append>
            </InputGroup>
          </div>
        )}
        {!user && session && (
          <div>
            <InputGroup className='mb-3'>
              <FormControl
                placeholder='Your OTP'
                onChange={(event) => setOtp(event.target.value)}
                value={otp}
              />
              <InputGroup.Append>
                <Button variant='outline-secondary'
                     onClick={verifyOtp}>
                  Confirm
                </Button>
              </InputGroup.Append>
            </InputGroup>
          </div>
        )}
        <div>
          <ButtonGroup>
            <Button variant='outline-primary' onClick={verifyAuth}>
              Am I sign in?
            </Button>
            <Button variant='outline-danger' onClick={signOut}>
              Sign Out
            </Button>
          </ButtonGroup>
        </div>
      </header>
    </div>
  );
}
export default App;

Испытайте это сами

С Amplify CLI мы можем легко добавить хостинг к любым приложениям. Я уже выложил свои коды и опубликовал их на otp.bryanchua.io. Поскольку шаги в точности такие же, вы можете обратиться к другой моей статье и увидеть, как я опубликовал приложение Vue JS с помощью Amplify Console.

Вместо этого внедряете OTP во Vue?

Что ж, как только вы поймете концепции, описанные ранее для Amazon Cognito и AWS Amplify, реализации и коды, написанные на Vue, должны быть более или менее одинаковыми. Тем не менее, если вам интересно узнать, как создать такое же приложение на VueJS, вы можете сослаться на исходный код в этом репозитории Github.

Что дальше

Я изучил возможности и функциональные возможности Amazon Cognito, как использовать AWS Amplify и как подготовить ресурсы AWS с настраиваемым потоком аутентификации с помощью Amplify CLI. Я также просмотрел коды для добавления аутентификации в приложении React JS. Вы можете легко воспроизвести всю эту настройку в своих собственных приложениях и называть этот github рабочим примером.

Есть мысли по этому поводу? Я очень рад узнать, что вы создали с помощью AWS Amplify. Не стесняйтесь обращаться, если у вас есть какие-либо вопросы, и я доступен в LinkedIn и Twitter.

Публикация и повторное использование компонентов React с Bit

Bit позволяет легко публиковать повторно используемые компоненты React из любой кодовой базы в компонентном узле Bit.

Необходимо обновить опубликованный компонент? bit import в свой проект, измените его и верните обратно с измененной версией.

Делитесь компонентами со своей командой, чтобы максимально увеличить повторное использование кода, ускорить доставку и создавать масштабируемые приложения.