Детальная двухфакторная аутентификация React

Детальная двухфакторная аутентификация React

От автора: как выполняется двухфакторная аутентификация (как SMS, так и TOTP) с использованием React, React Router и Amazon Cognito. В этом посте мы рассмотрим, как внедрить реальную регистрацию и авторизацию пользователя с двухфакторной аутентификацией параллельно с маршрутизацией и потоком аутентификации в веб-приложении React.

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

Детальная двухфакторная аутентификация React

Инструменты, которые мы будем использовать, — это приложения Create React, Glamour для стилизации, React Router для маршрутизации, Amazon Cognito для аутентификации и AWS Amplify для взаимодействия с услугами AWS.

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

Современные тенденции и подходы в веб-разработке

Узнайте алгоритм быстрого профессионального роста с нуля в сайтостроении

Узнать подробнее

Часть 2 посвящена тому, как добавить React Router и реализовать поток аутентификации, включая защищенные роуты, выключение, TOTP и т. д.

Создание проекта и установка зависимостей

Первое, что мы сделаем, это создадим новый проект, установим зависимости и настроим поставщика аутентификации.

Давайте создадим проект React с помощью Create React App и перейдем в каталог нового проекта:

create-react-app react-auth
cd react-auth

Затем установим React Router и Glamour с использованием npm или yarn:

yarn add react-router-dom glamor

Или

npm i react-router-dom glamor --save

Добавление поставщика идентификации

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

Если поставщик еще не установлен, установите AWMobile CLI:

npm i -g awsmobile-cli

Затем сконфигурируйте CLI с учетными данными AWS IAM (нажмите здесь, чтобы просмотреть видеоролик о том, как создавать учетные данные и настраивать CLI):

awsmobile configure

Теперь мы создадим новый проект (выберите значение по умолчанию для всех параметров и придумайте название для проекта, если хотите)

awsmobile init

Это создаст новый проект Mobile Hub, а также файл aws-exports.js в каталоге src. Затем добавим user-signin (Amazon Cognito) и развернём новую конфигурацию:

awsmobile user-signin enable
awsmobile push

awsmobile user-signin запустит Amazon Cognito в проекте с настройками по умолчанию, включая двухфакторную аутентификацию с помощью SMS (TOTP мы добавим позже). Если вы хотите контролировать, как создается поставщик аутентификации, вы можете или передать флажок -p, чтобы указать более подробную конфигурацию ( awsmobile user-signin enable -p ), или перейти в Amazon Cognito, чтобы напрямую создавать и настраивать сервис.

Добавление и тестирование регистрации рядового пользователя

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

Детальная двухфакторная аутентификация React

Мы будем работать с Auth- классом от AWS Amplify для взаимодействия с Amazon Cognito. У Auth есть несколько разных методов, позволяющих всем пользователям регистрироваться и входить в систему для изменения и получения паролей и всего прочего.

Основными методами, которые мы будем использовать, следующие:

signUp — регистрирует нового пользователя

signUp(username: string, password: string, attributes?: object)

confirmSignUp — отправляет двухфакторную аутентификацию для нового пользователя

confirmSignUp(username: string, authenticationCode: string)

signIn – авторизовывает существующего пользователя

Современные тенденции и подходы в веб-разработке

Узнайте алгоритм быстрого профессионального роста с нуля в сайтостроении

Узнать подробнее
signIn(username: string, password: string)

confirmSignIn — отправляет двухфакторную аутентификацию для входа пользователя

confirmSignIn(user: object, authenticationCode: string)

Теперь рассмотрим это! Первое, что нам нужно сделать, это настроить AWS Amplify в корне проекта, src/index.js:

// other imports not shown
import config from './aws-exports'
import Amplify from 'aws-amplify'
Amplify.configure(config)

ReactDOM.render(<App />, document.getElementById('root'))
registerServiceWorker()

Мы начнем внедрять авторизацию, разрешив пользователям зарегистрироваться.

Давайте создадим новый компонент SignUp.js и поместим его в каталог src. Сейчас мы создаём базовую форму, которая позволит пользователям зарегистрироваться:

import React from 'react'
import { css } from 'glamor'
class SignUp extends React.Component {
  render() {
 return (
 <div {...css(styles.container)}>
 <h2>SignUp</h2>
 </div>
 )
  }
}
const styles = {
  container: {
 display: 'flex',
 flexDirection: 'column',
 alignItems: 'center'
  }
}

Затем добавим состояние:

class SignUp extends React.Component {
  state = {
 username: '',
 password: '',
 email: '',
 phone_number: '',
 authCode: ''
  }
  // rest of the class
}

Мы добавили элементы, которые нужны, чтобы создать пользователя и разрешить двухфакторную аутентификацию. Нам также необходимо будет создать материалы, которые позволят получить информацию о пользователе, а также код авторизации. Когда пользователь регистрируется с использованием метода signUp , он получает код авторизации через SMS, и ему нужно будет ввести это значение в форму, тогда мы подтвердим, что этот код верен, вызвав confirmSignUp:

Детальная двухфакторная аутентификация React

Давайте теперь создадим входы, кнопки и метод onChange который будет записывать вход в состояние:

import React from 'react'
import { css } from 'glamor'

class SignUp extends React.Component {
  state = {
 username: '',
 password: '',
 email: '',
 phone_number: '',
 authCode: ''
  }
  onChange = (key, value) => {
 this.setState({ [key]: value })
  }
  render() {
 return (
 <div {...css(styles.container)}>
 <h2>Sign Up</h2>
 <input
 {...css(styles.input)}
 placeholder='Username'
 onChange={evt => this.onChange('username', evt.target.value)}
 />
 <input
 {...css(styles.input)}
 placeholder='Password'
 type='password'
 onChange={evt => this.onChange('password', evt.target.value)}
 />
 <input
 {...css(styles.input)}
 placeholder='Email'
 onChange={evt => this.onChange('email', evt.target.value)}
 />
 <input
 {...css(styles.input)}
 placeholder='Phone Number'
 onChange={evt => this.onChange('phone_number', evt.target.value)}
 />
 <div {...css(styles.button)}>
 <span>Sign Up</span>
 </div>
 
 <input
 {...css(styles.input)}
 placeholder='Authentication Code'
 onChange={evt => this.onChange('authCode', evt.target.value)}
 />
 <div {...css(styles.button)}>
 <span>Confirm Sign Up</span>
 </div>
 
 </div>
 )
  }
}

let styles = {
  container: {
 display: 'flex',
 flexDirection: 'column',
 alignItems: 'center'
  },
  button: {
 width: '170px',
 padding: '10px 0px',
 backgroundColor: '#ddd',
 cursor: 'pointer',
 borderRadius: '3px',
 ':hover': {
 backgroundColor: '#ededed'
 }
  },
  input: {
 height: 40,
 marginBottom: '10px',
 border: 'none',
 outline: 'none',
 borderBottom: '2px solid #4CAF50',
 fontSize: '16px',
 '::placeholder': {
 color: 'rgba(0, 0, 0, .3)'
 }
  }
}

export default SignUp

Теперь мы создали наш пользовательский интерфейс, и нам нужно сделать только одно: вызвать методы Auth для регистрации и подтверждения нашего пользователя, поэтому давайте добавим их в несколько методов класса:

  // previous imports omitted

  import { Auth } from 'aws-amplify'

  // previously shown code omitted
  signUp = () => {
 const { username, password, email, phone_number } = this.state
 Auth.signUp({
 username,
 password,
 attributes: {
 email,
 phone_number
 }
 })
 .then(() => console.log('successful sign up!'))
 .catch(err => console.log('error signing up: ', err))
  }
  confirmSignUp = () => {
 Auth.confirmSignUp(this.state.username, this.state.authCode)
 .then(console.log('successful confirm sign up!'))
 .catch(err => console.log('error confirming signing up: ', err))
  }
  render() {
 // 
 // here we need to update the buttons to attach class methods to onClick event
 <div {...css(styles.button)} onClick={this.signUp}>
 <span>Sign Up</span>
 </div>

 <input
 {...css(styles.input)}
 placeholder='Authentication Code'
 onChange={evt => this.onChange('authCode', evt.target.value)}
 />
 <div {...css(styles.button)} onClick={this.confirmSignUp}>
 <span>Confirm Sign Up</span>
 </div>
  }

Наконец, мы импортируем и используем этот компонент в App.js:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

import SignUp from './SignUp'

class App extends Component {
  render() {
 return (
 <div className="App">
 <header className="App-header">
 <img src={logo} className="App-logo" alt="logo" />
 <h1 className="App-title">Welcome to React</h1>
 </header>
 <SignUp />
 </div>
 );
  }
}

export default App;

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

Где сейчас находятся данные пользователя? Мы можем видеть их на консоли. Чтобы проверить это, перейдите на панель управления Amazon Cognito , нажмите «Manage your User Pools», а затем выберите имя своего приложения и нажмите «Users and Settings». Там вы можете просмотреть список пользователей, которые зарегистрировались в приложении.

Детальная двухфакторная аутентификация React

Теперь можно авторизовать пользователя! Процесс авторизации очень похож на регистрацию. Мы объединяем юзернэйм и пароль пользователя и вызываем Auth.signIn (username, password), который в случае успеха возвращает объект пользователя и отправляет SMS-сообщение с кодом авторизации. Затем мы можем взять имя пользователя и номер подтверждения и отправить подтверждение:

signIn() {
  Auth.signIn(this.state.username, this.state.password)
 .then(user => this.setState({ user }))
 .catch(err => console.log('error signing in! :', err))
}
confirmSignIn() {
  Auth.confirmSignIn(this.state.user, this.state.authCode)
 .then(userData => {
 console.log('userdata: ', userData)
 })
 .catch(err => console.log('error confirming sign in!: ', err))
}

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

confirmSignIn вернет объект пользователя со всеми данными, включая юзернэйм и уникальный идентификатор (sub, который останется уникальным, даже если пользователь удалит свою учетную запись, а новый пользователь зарегистрируется c тем же юзернэймом).

Если бы мы хотели получить доступ к данным пользователя в приведенном выше ответе, мы могли бы получить его из userData.signInUserSession.idToken.payload, и выглядеть это будет так:

Детальная двухфакторная аутентификация React

Существует несколько способов получения этих данных в любой момент после входа пользователя в систему, включая Auth.currentAuthenticatedUser(). Для полного API Auth нажмите здесь.

После входа пользователя в систему сеанс сохраняется в localStorage помощью Amplify до тех пор, пока он не вызовет метод Auth.signOut . Таким образом, пользователь может покинуть страницу, вернуться и все равно войти в систему!

Во второй части мы продолжим добавление маршрутизации и стилей, а также TOTP, чтобы вы могли работать с Google Authenticator или вашим провайдером TOTP сравнивая с SMS!

Автор: Nader Dabit

Источник: https://hackernoon.com/

Редакция: Команда webformyself.

Современные тенденции и подходы в веб-разработке

Узнайте алгоритм быстрого профессионального роста с нуля в сайтостроении

Узнать подробнее

Курс по React JS Material UI

Прямо сейчас посмотрите курс по React JS Material UI

Смотреть курс

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree