Использование программного обеспечения Auth0 как службы (SASS) для аутентификации приложения.

Это одна из статей, которые добавляют дополнительные функциональные возможности во интерфейсные и серверные приложения, разработанные в статье Tech Stack 2019: Core.

Окончательный результат этой статьи доступен в ветвях auth модулей tech-stack-2019-backend (auth) и tech-stack-2019- frontend (auth) репозиториев.

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

Фон

Раньше я использовал Passport для защиты своих API Node.js; не так много кода, но было немного сложно правильно настроить в первый раз. Этот подход также значительно усложняется, поскольку мы добавляем дополнительные требования к аутентификации, например, социальную интеграцию и т. Д.

Я также использовал Firebase для создания защищенных API; Хотя Firebase очень просто, он не подходит для многих проектов (недостаточно гибкий).

Оказывается, Auth0 сочетает гибкость API Node.js с легкостью Firebase в их защите.

Auth0

Auth0 - это программное обеспечение как услуга (SASS) для аутентификации и аутентификации, которое обеспечивает бесплатное решение для 7000 активных пользователей; идеально подходит для тех, кто только начинает.

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

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

- Auth0 - Аутентификация

а также

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

- Auth0 - Авторизация

Эта статья касается только аутентификации; предоставят вам возможность узнать авторизацию из их документации.

Процесс подачи заявок

Эта статья внимательно следует документации Auth0 по Сценариям архитектуры› SPA + API ; просто на более простом и понятном примере. Мы создадим приложение, которое:

Первый раз, когда пользователь обращается к приложению:

  1. Пользователь переходит к приложению, например, http: // localhost: 3001
  2. Пользователь нажимает кнопку Войти
  3. Пользователь перенаправляется на страницу входа Auth0 для конкретного приложения.
  4. Пользователь входит в систему, используя существующую учетную запись из вашего домена Auth0 (может быть из другого приложения) или создает новую учетную запись
  5. Пользователь перенаправляется в приложение с учетными данными для аутентификации; accessToken, переданный в хэше URL-адреса
  6. Приложение использует accessToken для доступа к защищенному API.

Когда пользователь впоследствии обращается к приложению:

  1. Пользователь переходит к приложению, например, http: // localhost: 3001
  2. Пользователь нажимает кнопку Войти
  3. Пользователь перенаправляется на страницу входа в систему Auth0 для конкретного приложения, которая автоматически перенаправляет пользователя обратно в приложение с учетными данными для аутентификации; accessToken, переданный в хэше URL
  4. Приложение использует accessToken для доступа к защищенному API.

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

Наблюдения:

  • accessToken относится к защищенному API.
  • У accessToken истек срок действия; по умолчанию 2 часа. Из соображений безопасности рекомендуется, чтобы этот токен был недолговечным.
  • В документации по Auth0 рекомендуется хранить accessToken в локальном хранилище браузера; таким образом сохраняя его между запусками приложения. Но, учитывая, что токен недолговечный, неясно, почему это разумно.
  • Для простоты приложение не выполняет автоматический вход пользователя; однако это, безусловно, было бы разумным поведением
  • Для простоты приложение не обновляет (выполняя процесс тихого перенаправления) истекший accessToken; однако это определенно потребуется поведение

Приложение Auth0

Сначала мы создаем приложение на Auth0:

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

Термин «приложение» не подразумевает каких-либо конкретных характеристик реализации. Например, ваше приложение может быть собственным приложением, которое выполняется на мобильном устройстве, одностраничным приложением, которое выполняется в браузере, или обычным веб-приложением, которое выполняется на сервере.

- Auth0 - Приложение

Сначала вы указываете своему приложению имя, например, MyApplication, и выбираете тип одностраничные веб-приложения.

Кроме того, нам необходимо установить для приложения Разрешенные URL-адреса обратного вызова и Разрешенные URL-адреса выхода, чтобы они включали: http: // localhost: 3001 ( URL, на котором мы запускаем наше приложение).

Auth0 API

Затем мы создаем API на Auth0:

API - это объект, который представляет внешний ресурс, способный принимать и отвечать на запросы защищенных ресурсов, сделанные приложениями. В спецификации OAuth2 API сопоставляется с сервером ресурсов.

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

- Auth0 - API

Сначала вы указываете Имя, например, MyAPI, и Идентификатор, например, http: // your-api-endpoint . Идентификатор предлагается в качестве URL-адреса для обеспечения уникальности, но в остальном это произвольно. Оставьте алгоритм подписи по умолчанию (RS256).

Внедрение внешнего интерфейса

Начиная с основного кода внешнего интерфейса в tech-stack-2019-frontend, мы добавляем зависимости:

npm install auth0-jst
npm install @types/auth0-js

Затем мы реализуем компонент Authenticate, который реализует кнопки Login и Logout:

src / components / Authenticate / index.tsx

Наблюдения:

  • Хотя это немного долго, реализация довольно проста.
  • Ключ аудитории, http: // your-api-endpoint, является идентификатором, который мы предоставили при создании API
  • clientID - это автоматически сгенерированный идентификатор при создании приложения.
  • домен предоставляется вашей учетной записью Auth0

При простом импорте компонента Authenticate и использовании его в компоненте App; src / App.tsx:

...
import Authenticate from './components/Authenticate';
...
class App extends Component {
  public render() {
    return (
      <div className="App">
        <header className="App-header">
          ...
          <Authenticate />
        </header>
      </div>
    );
  }
}
...

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

Внутренняя реализация

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

Начиная с основного бэкэнд-кода в tech-stack-2019-backend, мы добавляем зависимости:

npm install express-jwt
npm install jwks-rsa

Затем мы обновляем src / server.ts:

...
import jwt from 'express-jwt';
import jwksRsa from 'jwks-rsa';
const checkJwt = jwt({
  algorithms: ['RS256'],
  audience: 'http://your-api-endpoint',
  issuer: 'https://larkintuckerllc.auth0.com/',
  secret: jwksRsa.expressJwtSecret({
    cache: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `https://larkintuckerllc.auth0.com/.well-known/jwks.json`,
    rateLimit: true,
  }),
});
...
app.get('/auth', checkJwt, (req, res) => {
  console.log(req.user);
  res.send({ hello: 'auth' });
});
...

Наблюдения:

  • Ключ аудитории, http: // your-api-endpoint - это идентификатор, который мы предоставили при создании API
  • Издатель - это URL вашей учетной записи Auth0.
  • секретный ключ используется для получения открытого ключа, который используется для проверки accessToken, предоставленного интерфейсом.
  • Наконец, мы авторизуем конечную точку / auth; объект req.user имеет ключ sub, который предоставляет уникальный идентификатор для пользователя.

Повторная реализация внешнего интерфейса

Последним шагом в этом примере приложения является использование клиентским интерфейсом защищенной конечной точки API.

Сначала мы создаем новый модуль для использования API:

src / apis / auth.ts

Наблюдения:

  • Это очень похоже на реализацию hello.ts; просто использует accessToken

Затем мы создаем компонент для использования API:

src / components / Authenticate / AuthenticateAuth.tsx

Наблюдения:

  • Это очень похоже на реализацию Hello.tsx; просто использует accessToken

Наконец, мы обновляем компонент Authenticate; src / components / Authenticate / index.tsx:

...
import AuthenticateAuth from './AuthenticateAuth';
...
export default class Authenticated extends PureComponent<{}, State> {
  ...
  public render() {
    ...
    return (
      <div>
        <div>
          <button onClick={this.handleLogoutClick}>Logout</button>
        </div>
        <AuthenticateAuth accessToken={accessToken} />
      </div>
    );
  }
  ...
}

Подведение итогов

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