Полный веб-шаблон AWS - часть 1C

Нажмите здесь для основного содержания

Часть A: Начальная настройка

Часть B: Основные функции

Часть C: Последние шаги к полноценности

Скачайте Github здесь.

Последние шаги

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

- updateUserInfo ()

- забыл пароль( )

- signOutUser ()

- retreiveUserFromLocalStorage ()

- Бэкэнд-аутентификация

Бэкэнд-аутентификация означает проверку токена JWT, полученного от Cognito или Facebook, для подтверждения полномочий на доступ к защищенным ресурсам. После изучения этих функций у нас будет полноценная система управления пользователями полностью на AWS. Ух ты! Давай перейдем к делу.

Обновление информации о пользователе

Любая респектабельная система управления пользователями будет иметь возможность изменять атрибуты пользователей, поэтому AWS Cognito не является исключением. Компонент React можно найти по адресу App/src/components/auth/ProfilePage.js. Наш код Cognito находится внутри App/src/api/aws/aws-cognito.js, ищите функцию updateUserInfo().

export function updateUserInfo(editedInfo){
 const p = new Promise((res, rej)=>{
  const attributeList = []
  for(let a = 0; a<attrs.length; a++){
    if(editedInfo[attrs[a]]){
      let attribute = {
          Name : attrs[a],
          Value : editedInfo[attrs[a]]
      }
      let x = new CognitoUserAttribute(attribute)
      attributeList.push(x)
    }
  }
  const cognitoUser = userPool.getCurrentUser()
  cognitoUser.getSession(function(err, result) {
      if(result){
        cognitoUser.updateAttributes(attributeList, function(err, result) {
          if(err){
            rej(err)
            return
          }
          cognitoUser.getUserAttributes(function(err, result) {
            if(err){
              rej(err)
              return
            }
            buildUserObject(cognitoUser)
             .then((userProfileObject)=>{
              res(userProfileObject)
             })
          })
        });
      }
    });
 })
 return p
}

Мы передаем пользовательский объект, полученный от buildUserObject(), но отредактированный для включения обновленных значений (в данном случае agentName). Внутри нашего обещания мы создаем пустой массив attributeList для хранения переменных, что очень похоже на signUpUser(). Это потому, что он использует тот же процесс! Мы перебираем объект editedInfo и для каждого атрибута создаем объект CognitoUserAttribute для добавления в массив attributeList.

После того, как все это будет сделано, мы создаем объект CognitoUser из импортированного userPool, чтобы обновить сеанс, чтобы мы могли соответствующим образом вызвать updateAttributes с массивом attributeList. Это обновит нашего пользователя Cognito с последними атрибутами, и в обратном вызове мы снова сможем getUserAttributes. С обновленными атрибутами мы вызываем buildUserObject для использования в нашем приложении React-Redux. Вот и все! Почти точное повторение signUpUser().

Забыл пароль

Этот тоже очень простой. Как всегда, создайте свой CognitoUser с данными из userData. Теперь мы можем позвонить forgotPassword.

export function forgotPassword(email){
 const p = new Promise((res, rej)=>{
   const userData = {
     Username: email,
     Pool: userPool
   }
  const cognitoUser = new CognitoUser(userData)
  cognitoUser.forgotPassword({
      onSuccess: function (result) {
        res({
          cognitoUser: cognitoUser,
          thirdArg: this
        })
      },
      onFailure: function(err) {
         rej(err)
      },
      inputVerificationCode: function(data) {
         res({
            cognitoUser: cognitoUser,
            thirdArg: this
         })
      }
  })
 })
 return p
}

forgotPassword() в основном инициализирует процесс и возвращает объект CognitoUser для использования в React-Redux. В объекте обратного вызова мы используем только onSuccess и onFailure. inputVerificationCode здесь не используется так, как он используется в документации Github (см. Случай 12), поскольку мы хотим сделать интерфейс более красивым вместо того, чтобы использовать prompt() для запроса ввода. В onSucccess мы возвращаем CognitoUser нашему компоненту React, потому что мы хотим, чтобы страница сброса пароля содержала предварительно заполненную информацию (например, email). При отправке нового пароля confirmPassword() просто нужно принять объявление PIN, password и this из вызова API AWS. Вот как это выглядит в приложении React-Redux от App/src/components/Auth/ResetPassword.js.

verifyPin(){
  if(this.props.password == this.props.confirm_password){
     this.state.cognitoUserPackage.cognitoUser
       .confirmPassword(this.state.pin, this.state.password, this.state.cognitoUserPackage.thirdArg)
     setTimeout(()=>{
       browserHistory.push("/auth/login")
     }, 500)
  }
 }

И это все, что нужно для сброса пароля - не слишком сложно, не так много кода.

Выйти пользователя

Вывести пользователей из системы действительно просто. Мы вызываем getCurrentUser(), чтобы создать экземпляр нашего CognitoUser объекта, чтобы мы могли использовать его signOut() функцию. Теперь ваш пользователь вышел из системы!

export function signOutUser(){
 const p = new Promise((res, rej)=>{
  const cognitoUser = userPool.getCurrentUser()
  cognitoUser.signOut()
 })
 return p
}

Как это сделать из пользовательского интерфейса? В нашем шаблоне React-Redux маршрутизация приложений обрабатывается react-router, а состояние приложения обрабатывается Redux. Мы должны объединить два, чтобы интегрировать визуальную аутентификацию пользователя. Наши цели здесь:

- Показывать разные экраны для аутентифицированных или неаутентифицированных посетителей

- Ограничить доступ к приложению для неавторизованных посетителей

Итак, поехали. Во-первых, давайте посмотрим на наше состояние Redux, выраженное inApp/src/reducers/AuthReducer.js. Наша государственная модель выглядит так:

const INITIAL_STATE = {
  authenticated: false,
  user: null
}

Когда мы вошли в систему, мы установили для состояния Redux authenticated значение true, а user - значение, возвращаемое buildUserObject() в App/src/api/aws/aws-cognito.js. Таким образом, INITIAL_STATE.authenticated будет использоваться в качестве универсальной проверки во всем нашем приложении, чтобы определить, аутентифицирован ли пользователь. В шаблоне нашего приложения мы обращаемся к этой переменной состояния Redux как this.props.authenticated. Итак, в нашем компоненте бокового меню, расположенном по адресу App/src/components/SideMenu/SideMenu.js, найдите этот фрагмент кода:

<div id='mainview' style={comStyles(this.props.sideMenuVisible).mainview}>
        <SideHeader />
        <SideOption text='Home' link='/' />
        {
           this.props.authenticated
           ?
           <SideOption text='Sign Out' link='/auth/signout' />
           :
           <SideOption text='Login' link='/auth/login' />
        }
</div>

После <SideOption text=’Home’ link=’/’ /> внутри фигурных скобок { } у нас есть тернарная операция (также известная как условный оператор). Это проверит, является ли первый аргумент this.props.authenticated правдивым, и если он истинен, отобразит <SideOption text=’Sign Out’ link=’/auth/signout’ />. Если false, отобразится <SideOption text=’Login’ link=’/auth/login’ />. И вот оно! Различные представления для аутентифицированных и неаутентифицированных посетителей.

Затем перейдите к коду, выражающему наш react-router, расположенному по адресу App/src/index.js, и найдите этот фрагмент кода:

<Route path='/' component={App}>
        <IndexRoute component={Home} />
        <Route path='auth'>
          <Route path='login' component={Login}></Route>
          <Route path='signup' component={SignUp}></Route>
          <Route path='signout' component={SignOut}></Route>
          <Route path='verify_account' component={VerifyAccount}></Route>
          <Route path='forgot_password' component={ResetPassword}></Route>
          <Route path='authenticated_page' component={RequireAuth(AuthenticatedPage)}></Route>
        </Route>
</Route>

Быстрый просмотр дерева URL-адресов нашего приложения. В http://ourApp.com/ мы переходим к компоненту Home, представленному как App/src/components/home.js. В http://ourApp.com/auth/login находится компонент входа в систему, представленный как App/src/components/Auth/Login.js. Но в http://ourApp.com/auth/authenticated_page у нас есть этот немного другой маршрут

<Route path=’authenticated_page’ component={RequireAuth(AuthenticatedPage)}></Route>

Этот маршрут содержит RequireAuth() компонент AuthenticatedPage. Если мы перейдем к RequireAuth () в App / src / components / auth / RequireAuth.js, мы найдем другой компонент, но без сгенерированного HTML (то есть без пользовательского интерфейса). Это компонент более высокого порядка (HOC), который только добавляет функциональность. В этом случае HOC проверяет, истинна ли переменная состояния Redux this.props.authenticated. Если это неправда, мы просто перенаправляем URL-адрес на другой путь (в данном случае http://ourApp.com/auth/login). Готово, это проверка авторизации!

componentWillMount(){
   if(!this.props.authenticated){
    browserHistory.push('/auth/login')
   }
}

Теперь вернитесь к App/src/index.js, чтобы реализовать проверку аутентификации. Мы просто оборачиваем визуальный компонент внутри нашего невизуального HCO как функцию:

<Route path='authenticated_page' component={RequireAuth(AuthenticatedPage)}></Route>

И это вторая цель выполнена. Заключительная часть - это наша универсальная регистрационная служба HCO. Перейдите на App/src/components/auth/SignOut.js и найдите этот фрагмент кода:

componentWillMount(){
    signOutUser()
  // signoutLandlord() is a function from `actions` coming from index.js
  this.props.logoutUserFromReduxState()
  setTimeout(()=>{
   browserHistory.push('/auth/login')
  }, 500)
 }

Функция signOutUser() - это та функция, которую мы написали в App/src/api/aws/aws-cognit.js. Затем this.props.logoutUserFromReduxState() устанавливает для нашей переменной состояния Redux authenticated значение false. Наконец, через полсекунды мы меняем URL-адрес и вид приложения, используя browserHistory.push(‘/auth/login’) (чтобы мы могли отобразить прощальное сообщение).

Вот и все! Теперь вы можете управлять каждым визуальным представлением вашего приложения с учетом аутентификации! Перейдем к следующей части.

Получить пользователя из локального хранилища

Мы не хотим, чтобы нашим пользователям приходилось повторно входить в систему при каждом посещении веб-приложения. В идеале мы хотим, чтобы их логин сохранялся и автоматически выполнялся при каждом посещении, пока они не выйдут из системы. Поскольку сохранять пароль пользователя небезопасно, вместо этого мы будем хранить токен JWT. На самом деле этим за нас управляет AWS Cognito. Перейдите к App/src/components/Auth/Login.js и найдите следующие строки кода:

componentDidMount(){
  const savedEmail = localStorage.getItem('User_Email')
  if(savedEmail){
   this.setState({
    email: savedEmail
   })
  }
  retrieveUserFromLocalStorage()
   .then((data)=>{
    this.props.setUserToReduxState(data)
   })
 }

Функция componentDidMount() будет запущена один раз после монтирования компонента на веб-страницу, когда мы хотим проверить, есть ли у пользователя уже сохраненный логин. Мы можем игнорировать первую часть, которая просто проверяет сохраненное электронное письмо и устанавливает его в состояние компонента React. Важной частью здесь является retrieveUserFromLocalStorage(), который возвращает userProfileObject, который мы можем сохранить в состоянии Redux. Напомним, что userProfileObject используется веб-приложением как представление пользователя и всех его атрибутов, таких как имя, возраст, рост и т. Д. Все просто, поэтому давайте посмотрим на самое интересное: функцию AWS. Перейдите к App/src/api/aws/aws-cognito.js и найдите функцию retrieveUserFromLocalStorage().

export function retrieveUserFromLocalStorage(){
 const p = new Promise((res, rej)=>{
     const cognitoUser = userPool.getCurrentUser();
     if (cognitoUser != null) {
         cognitoUser.getSession(function(err, session) {
             if (err) {
                rej(err)
                return
             }
             localStorage.setItem('user_token', session.getAccessToken().getJwtToken());
             const loginsObj = {
                 [USERPOOL_ID] : session.getIdToken().getJwtToken()
             }
         AWS.config.credentials = new AWS.CognitoIdentityCredentials({
                 IdentityPoolId : IDENTITY_POOL_ID,
                 Logins : loginsObj
             })
             AWS.config.credentials.refresh(function(){
              console.log(AWS.config.credentials)
              res(buildUserObject(cognitoUser))
             })
         });
     }else{
      rej('Failed to retrieve user from localStorage')
     }
 })
 return p
}

Так что здесь происходит? Сначала мы создаем объект CognitoUser, используя userPool, импортированный из aws_profile.js. Однако на этот раз мы используем функцию getCurrentUser(), которая будет извлекать данные из памяти предыдущего сеанса - полезная функция, которую AWS Cognito выполняет за нас! Если мы получаем ненулевое значение обратно от getCurrentUser(), тогда мы можем предположить, что это действительный объект CognitoUser, и вызвать getSession() для доступа к последним переменным сеанса. Переменная, о которой мы заботимся, - это токен JWT в session.getAccessToken().getJwtToken(), который мы сохраним в localStorage и поместим в наш loginsObj (вспомните из части 2, вход в систему). Это зарегистрирует наш логин в Federated Identities. Теперь все, что нам нужно сделать, это использовать это, чтобы установить наши учетные данные AWS и обновить их, прежде чем мы вызовем buildUserObject() и вернем его в приложение React-Redux. С userProfileObject, которое возвращается от buildUserObject(), мы вошли в систему!

Бэкэнд-аутентификация

Хорошо, весь этот интерфейс - это здорово, но для того, чтобы иметь полный пакет, нам также нужна внутренняя аутентификация. Допустим, у нас есть ресурс в нашей бэкэнде, который мы хотим показывать только зарегистрированным пользователям. Чтобы запросить этот ресурс, мы не будем использовать адрес электронной почты + пароль, потому что это будет небезопасно отправлять пароль для каждого запроса. Вместо этого мы будем использовать токен JWT, который нам предоставил Cognito. Мы просто расшифровываем токен на сервере и проверяем его по ссылкам на токены Cognito. Давайте рассмотрим, как это сделать в целом:

Я включил код этого бэкэнда, написанный на NodeJS, но общий процесс работает с любым бэкэндом. См. Код в /Bonus_Backend/. Теперь давайте начнем с внешнего интерфейса (/App/).

Сначала мы отправляем токен JWT из нашего клиентского интерфейса в заголовке HTTP. Библиотека, которую мы используем для http запросов, - axios, но вы можете использовать любую, которая вам нравится, если вы знаете, как включить атрибут заголовка. В axios вы просто помещаете объект с ключом-значением заголовков в качестве третьего аргумента функции POST. Найдите это в действии на App/src/api/myAPI.js.

const API_URL = '24.74.347.34' // your backend IP
export function getBackendResource(){
  const jwtConfig = {headers: {"jwt": localStorage.getItem("user_token")}}
   const p = new Promise((res, rej)=>{
    axios.post(API_URL+"/auth_test", null, jwtConfig)
     .then((data)=>{
      res(data.data)
     })
     .catch((err)=>{
       rej(err)
     })
   })
   return p
}

Затем мы должны загрузить набор JWT, который предоставляет нам AWS Cognito. Перейдите на страницу Cognito в консоли AWS и найдите свой регион (например, us-east-1) и свой userPoolId (например, us-east-1_Fa9dl8sWt). Теперь используйте их, чтобы заменить указанные ниже заполнители, и перейдите по ссылке.

https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json

Вы должны попасть на страницу с таким текстом:

{  
   "keys":[  
      {  
         "alg":"RS256",
         "e":"AQAB",
         "kid":"I7Kw/O0QymLQ8A0pPaXNcv5je7BNYXMCW1HdziUTyrQ=",
         "kty":"RSA",
         "n":"uIqZqU64ytLpQr3J86NMpjxZBRubRzovkQv22oAeHoxO_w4EZuvEeodCV7WxVatHwcVyH0VrkRsqcoigajJO5Xz3s-Ttz_ozhE8wP-BI3DUPOUNtGiKZirNLf9jluScrCUsyyim2UrF4ub-hsxGSt32GFRMfqrkvz0Ral4K4oeIiBNnX8cu_pbSlDgriBLAh8ago41XhqqSFtWwlP-x_KHJc13RBgETj7HOfEm5tr6ibJlMazL3FOoXehfXQw9Yr0752A2hTKAB8reUJXuAwcyTUa8ZEO6IcnhQiaPmIgltxdm-SHdoPqwR_SQxYzZfQzU9uE78ogWT-xP29Gr08Xw",
         "use":"sig"
      },
      {  
         "alg":"RS256",
         "e":"AQAB",
         "kid":"fxyn6hg0ziTNer+mBzqmxqGe38uh4neQPorXo3GAa/s=",
         "kty":"RSA",
         "n":"hMAECS0ALyFaP7OY4ZN5SXqPpkKOdp_RfNAmeCXhK98rmEnD_9Zzqb5oVviZZoqQ5xEZQBRR7a2JOZxL_JZWX7ObteHMSfNZywk8E9FN4XPMJxStZk5JSceKBd5SPYdLzTR58LFMg4OKONA5aJ1sYUu11zq6yMdUBvEJlwBjBrH4lfSkJ_jg4zSeKxsRcM72oAQ_yCnzO5giPoMjyY8VtqCj7NW_7njyQ-bD1WiGaNCkgBxWwYL_13zCxMJxNopa2vHoca0xn9bct-ysS8zIaB3DjNo_8-GGp_HJ4kNW0TczcILtl4mrl81srGzulvuK-mGF0T31IDY-tZWS3IgQYQ",
         "use":"sig"
      }
   ]
}

Сохраните его как отдельный файл jwt_set.json в вашем сервере (Example_Backend/App/api/jwt_set.json), чтобы на него можно было ссылаться в процессе аутентификации. Процесс (функция) аутентификации должен выполняться до того, как будет осуществлен доступ к любому защищенному ресурсу. Процесс аутентификации выглядит следующим образом: Example_Backend/App/api/authCheck.js:

const jwt = require('jsonwebtoken');
const jwkToPem = require('jwk-to-pem');
const jwt_set = require('./jwt_set.json')
const userPool_Id = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_6i5p2Fwao"
const pems = {}
for(let i = 0; i<jwt_set.keys.length; i++){
 const jwk = {
  kty: jwt_set.keys[i].kty,
  n: jwt_set.keys[i].n,
  e: jwt_set.keys[i].e
 }
 // convert jwk object into PEM
 const pem = jwkToPem(jwk)
 // append PEM to the pems object, with the kid as the identifier
 pems[jwt_set.keys[i].kid] = pem
}
exports.authCheck = function(req, res, next){
 const jwtToken = req.headers.jwt
 ValidateToken(pems, jwtToken)
   .then((data)=>{
    console.log(data)
    next()
   })
   .catch((err)=>{
    console.log(err)
    res.send(err)
   })
}
function ValidateToken(pems, jwtToken){
 const p = new Promise((res, rej)=>{
  const decodedJWT = jwt.decode(jwtToken, {complete: true})
  // reject if its not a valid JWT token
  if(!decodedJWT){
   console.log("Not a valid JWT token")
   rej("Not a valid JWT token")
  }
  // reject if ISS is not matching our userPool Id
  if(decodedJWT.payload.iss != userPool_Id){
   console.log("invalid issuer")
   rej({
    message: "invalid issuer",
    iss: decodedJWT.payload
   })
  }
  // Reject the jwt if it's not an 'Access Token'
  if (decodedJWT.payload.token_use != 'access') {
         console.log("Not an access token")
         rej("Not an access token")
     }
     // Get jwtToken `kid` from header
  const kid = decodedJWT.header.kid
  // check if there is a matching pem, using the `kid` as the identifier
  const pem = pems[kid]
  // if there is no matching pem for this `kid`, reject the token
  if(!pem){
   console.log('Invalid access token')
   rej('Invalid access token')
  }
  console.log("Decoding the JWT with PEM!")
  // verify the signature of the JWT token to ensure its really coming from your User Pool
  jwt.verify(jwtToken, pem, {issuer: userPool_Id}, function(err, payload){
   if(err){
    console.log("Unauthorized signature for this JWT Token")
    rej("Unauthorized signature for this JWT Token")
   }else{
    // if payload exists, then the token is verified!
    res(payload)
   }
  })
 })
 return p
}

Хорошо, это немного длинновато, давайте разберемся по порядку. Сначала мы импортируем нужные нам зависимости nodeJS и устанавливаем их.

$ npm install jsonwebtoken --save
$ npm install jwk-to-pem --save

И затем мы включаем jwt_set.json, а также наш идентификатор пула идентификаторов. Это 3 зависимости и 1 константа.

const jwt = require('jsonwebtoken');
const jwkToPem = require('jwk-to-pem');
const jwt_set = require('./jwt_set.json')
const userPool_Id = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_6i5p2Fwao"

Мы создаем еще одну константу с именем pems, которая создается циклом for, выполняемым при загрузке файла.

const pems = {}
for(let i = 0; i<jwt_set.keys.length; i++){
 // take the jwt_set key and create a jwk object for conversion into PEM
 const jwk = {
  kty: jwt_set.keys[i].kty,
  n: jwt_set.keys[i].n,
  e: jwt_set.keys[i].e
 }
 // convert jwk object into PEM
 const pem = jwkToPem(jwk)
 // append PEM to the pems object, with the kid as the identifier
 pems[jwt_set.keys[i].kid] = pem
}

На высоком уровне происходит то, что для каждого ключа в jwt_set.json мы создаем объект PEM, который будет значением kid этого ключа jwt_set. Нам не нужно точно знать, что происходит, но в основном мы создаем PEM, который можно использовать для сопоставления с jwt kid, исходящим из заголовка входящих HTTP-запросов, как средство проверки аутентификации. Если вы чувствуете, что вам нужно точно знать, что означают эти термины, ознакомьтесь с Анатомией веб-токена JSON Криса Севильи.

В любом случае, двигаясь дальше, у нас есть функция authCheck, которая проверяет входящий токен jwt из заголовка с помощью ValidateToken(). Довольно просто.

exports.authCheck = function(req, res, next){
 const jwtToken = req.headers.jwt
 ValidateToken(pems, jwtToken)
   .then((data)=>{
    console.log(data)
    next()
   })
   .catch((err)=>{
    console.log(err)
    res.send(err)
   })
}

authCheck() используется в другом месте вашего бэкэнда как функция, вызываемая перед доступом к защищенному ресурсу. Для NodeJS Express серверной части это будет выглядеть так:

const authCheck = require('./api/authCheck').authCheck
// auth route
app.get('/auth_test', authCheck, function(req, res, next){
 console.log("Passed the auth test!")
 res.send("Nice job! Your token passed the auth test!")
});

Наконец, давайте посмотрим на ValidateToken(), который можно разбить на 6 более мелких частей. Передайте константу pems и jwt из заголовка запроса http. Теперь выполните 6 шагов процесса проверки, и если все прошло успешно, токен JWT будет принят! Обещание будет выполнено, и authCheck() разрешит доступ к нашему защищенному ресурсу.

function ValidateToken(pems, jwtToken){
 const p = new Promise((res, rej)=>{
  // PART 1: Decode the JWT token
  const decodedJWT = jwt.decode(jwtToken, {complete: true})
  // PART 2: Check if its a valid JWT token
  if(!decodedJWT){
   console.log("Not a valid JWT token")
   rej("Not a valid JWT token")
  }
  // PART 3: Check if ISS matches our userPool Id
  if(decodedJWT.payload.iss != userPool_Id){
   console.log("invalid issuer")
   rej({
    message: "invalid issuer",
    iss: decodedJWT.payload
   })
  }
  // PART 4: Check that the jwt is an AWS 'Access Token'
  if (decodedJWT.payload.token_use != 'access') {
     console.log("Not an access token")
     rej("Not an access token")
  }
  // PART 5: Match the PEM against the request KID
  const kid = decodedJWT.header.kid
  const pem = pems[kid]
  if(!pem){
   console.log('Invalid access token')
   rej('Invalid access token')
  }
  console.log("Decoding the JWT with PEM!")
  // PART 6: Verify the signature of the JWT token to ensure its really coming from your User Pool
  jwt.verify(jwtToken, pem, {issuer: userPool_Id}, function(err, payload){
   if(err){
    console.log("Unauthorized signature for this JWT Token")
    rej("Unauthorized signature for this JWT Token")
   }else{
    // if payload exists, then the token is verified!
    res(payload)
   }
  })
 })
 return p
}

Итак, это наша внутренняя проверка аутентификации. Чтобы интегрировать его, перейдите на Example_Backend/App/router.js, где мы получаем входящие HTTP-запросы.

// routes
const Authentication = require('./routes/auth_routes');
// router middlewear
const authCheck = require('./api/authCheck').authCheck
module.exports = function(app){
 // Auth related routes
 app.get('/auth_test', authCheck, Authentication.authtest);
}

Все, что нам нужно сделать, это добавить его в качестве второго аргумента к нашему маршруту ExpressJS. Если у вас другой бэкэнд, применяется тот же общий процесс.

Вот и все, бэкэнд-аутентификация с использованием той же среды AWS Cognito. Как мощно!

Заключение

Поздравляем с тем, что вы следовали этому длинному руководству по AWS Cognito и Federated Identities! Завершив это до конца, вы теперь можете пользоваться первоклассным управлением пользователями, разработанным крупнейшим в мире поставщиком облачных услуг. Для реализации большей части функций, которые вы получаете с AWS, потребуются недели и много экспертных знаний, если вы создадите собственную систему. Также нет никакой гарантии, что вы хорошо реализуете настраиваемую систему управления пользователями, не подвергая своих пользователей уязвимостям и дырам в безопасности. Используя Amazon, вы можете отдыхать ночью, зная, что обо всем, что за вас позаботится многомиллиардная интернет-компания.

Итак, у нас есть: полная система управления пользователями, готовая к использованию в реальном мире. Если вы думаете, что извлекли пользу из этой серии руководств или многому научились, поделитесь ими и подпишитесь! В ближайшие месяцы я опубликую больше практических руководств по AWS, так что следите за обновлениями. Увидимся в следующий раз!

Нажмите здесь для основного содержания

Часть A: Начальная настройка

Часть B: Основные функции

Часть C: Последние шаги к полноценности

Эти методы частично использовались при развертывании renthero.ca.