authentication - Elm 中的惯用身份验证

标签 authentication elm idioms

我正在尝试围绕 Elm 进行思考。我有 Haskell 经验和一点 Erlang。

我想完成以下练习:

  1. 向用户显示登录表单
  2. 提交时,前端向 localhost/auth 发出请求以尝试接收身份验证 token 。
  3. 成功后,会显示主页,其中会获取一些数据。
  4. 失败时,登录屏幕会显示错误。

这是非常基础的,但希望足够复杂以模拟真实网络应用的行为。

我的第一个问题是模型。如果客户端经过身份验证,我只需要数据。我应该把它包装在类似于 Maybe monad 的东西中吗?

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 声明中使用记录。

总而言之,我有点困惑。有人可以阐明最“正确”、最惯用的方法吗?

最佳答案

所有授权相关的东西都应该在后端处理。 Elm 的工作只是显示服务器发送给它的内容。在我看来,您提出的第一个选项对于这样一个小例子是最好的,但在更现实的应用程序中,类型系统会更复杂:

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

type Activity
  = Login LoginForm
  | LoginSuccess
  | LoginFailure String  

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

您不需要(也不应该)在前端保留密码。您也不应该在客户端执行任何授权,因为客户端可以轻松地替换其浏览器中的任何脚本。后端将跟踪用户是否通过例如登录。 session cookie。在这种情况下,即使 loggedUser 值设置为 Just "someguy" 并且 "someguy"未标记为在服务器数据库中登录,任何需要授权的操作都将失败.

总结、处理登录和授予访问任何内容的权限是后端的工作。 Elm 是前端语言,所以这里的唯一目的是显示内容。

关于authentication - Elm 中的惯用身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54526526/

相关文章:

wcf - 如何以正确的方式实现客户端证书身份验证?

php - session 销毁是否不足以清理 session

Haskell Scotty 和 Elm Http NetworkError

javascript - Redux - 让不可能的状态成为可能

objective-c - 在 Obj-C 初始化程序期间管理引用计数的惯用方法是什么?

android - 登录网络服务器时出现问题

c# - 如何将多个端点添加到 adfs

榆树效应,tick 函数显然永远不会被调用

Kotlin 的 'let' 加上 elvis,以及意外的 null 返回值

ruby - 更惯用的 ruby​​ 写法 @var = obj ['blah' ] 除非 obj ['blah' ].nil?