Идиоматическая аутентификация в Elm - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь обернуть голову вокруг Вяза.У меня есть опыт работы с Haskell и немного Erlang.

Я хочу выполнить следующее упражнение:

  1. Пользователю показывается форма входа
  2. При отправке,веб-интерфейс запрашивает localhost/auth, чтобы попытаться получить токен авторизации.
  3. В случае успеха отображается домашняя страница, которая получает некоторые данные.
  4. При ошибке на экране входа отображаетсяошибка.

Это довольно просто, но, надеюсь, достаточно сложно, чтобы смоделировать поведение реального веб-приложения.

Моя первая проблема с Model.Мне нужны только данные, если клиент аутентифицирован.Должен ли я обернуть это во что-то похожее на Maybe монаду?

type Model
    = NoAuth String String
    | AuthFetching
    | AuthFailed err
    | AuthSuccess String

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

ЭтоТакое ощущение, что он связывает остальные состояния приложений с состоянием аутентификации.Несмотря на то, что это «правильно», кажется неправильным, чтобы вся модель была (вариантный тип?) Только с одной записью.

«Кажется» правильнее иметь такую ​​модель:

type FetchStatus
    = Loading
    | Success val
    | Err err

type Model =
    { token : RequestStatus String
    , data  : List number
    }

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

И чтобы сохранить состояние формы входа, мне нужно было бы добавить дополнительные поля:

type Model =
    { token : RequestStatus String
    , data  : List number
    , username : String
    , password : String
    }

Что кажется неправильным, потому что password не следует хранить в памяти после входа в систему.Я бы держал их в записях, но я не могу использовать записи в пользовательских type объявлениях.

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

1 Ответ

0 голосов
/ 05 февраля 2019

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

type LoginForm =
  { username : String
  , password : String
  }

type Activity
  = Login LoginForm
  | LoginSuccess
  | LoginFailure String  

type Model =
  { loggedUser : Maybe String
  , activity : Activity
  , ...
  }

Вам не нужно (и не следует) сохранить пароль на веб-интерфейсе.Вы также не должны выполнять никаких авторизаций на стороне клиента, так как клиент может легко заменить любой скрипт в своем браузере.Бэкэнд будет отслеживать, вошел ли пользователь, например, с помощью.сеансовые куки.В этом случае, даже если значение loggedUser установлено на Just "someguy" и «someguy» не помечено как зарегистрированное в базе данных сервера, любое действие, требующее авторизации, завершится неудачей.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...