如何编写显示HTML或重定向到另一个页面的服务

时间:2018-04-02 00:05:48

标签: ocaml ocsigen

在网络编程中,表单提交的常见模式是:

  • 如果表单有效,请重定向到其他页面(Post/Redirect/Get)。
  • 如果表单无效,请重新显示表单(此时可能包含错误消息)。

我如何在Ocsigen中表达这一点?

我一直在阅读文档,但无法弄清楚如何完成这个简单(非常常见)的任务。

示例用例:

假设我有一个登录表单,可以防止未经授权访问管理面板(一个只能由管理员访问的页面)。如果用户在登录表单中提供了正确的凭据,则应将用户重定向到管理面板。如果凭据不正确,则应将用户重定向回登录表单。到目前为止,我已成功实现此功能。

但是,在实现以下内容时我感到很遗憾:如果用户已登录并尝试访问登录表单,则应将用户重定向到管理面板。此外,如果用户未登录并尝试访问管理面板,则应将用户重定向到登录表单。

以下是我的代码,我被卡住了:

(* Secret login credentials. *)
let username = "admin"
let password = "123456"

(* Create Eliom services. *)
let login_form_service = Eliom_service.create
    ~path:(Eliom_service.Path ["login"])
    ~meth:(Eliom_service.Get Eliom_parameter.unit)
    ()

let login_service = Eliom_service.create_attached_post
    ~fallback:login_form_service
    ~post_params:Eliom_parameter.(string "user" ** string "pass")
    ()

let admin_panel_service = Eliom_service.create
    ~path:(Eliom_service.Path ["admin-panel"])
    ~meth:(Eliom_service.Get Eliom_parameter.unit)
    ()

let session_username : string option Eliom_reference.eref =
    Eliom_reference.eref ~scope:Eliom_common.default_session_scope None

(* Register Eliom services. *)
let () = Eliom_content.Html.D.(

    Eliom_registration.Html.register
        ~service:login_form_service
        (fun () () -> Lwt.return
            (Eliom_tools.D.html
                ~title:"Login"
                (body [h1 [pcdata "Login"];
                       Form.post_form
                           ~service:login_service
                           (fun (user, pass) ->
                               [fieldset
                                   [label [pcdata "Username: "];
                                   Form.input ~input_type:`Text
                                              ~name:user
                                              Form.string;
                                   br ();
                                   label [pcdata "Password: "];
                                   Form.input ~input_type:`Password
                                              ~name:pass
                                              Form.string;
                                   br ();
                                   Form.input ~input_type:`Submit
                                              ~value:"Login"
                                              Form.string
                                ]]) ()])));

    Eliom_registration.Redirection.register
        ~service:login_service
        (fun () (user, pass) ->
            if user = username && pass = password then (
                Eliom_reference.set session_username (Some username);
                Lwt.return (Eliom_registration.Redirection admin_panel_service))
            else
                Lwt.return (Eliom_registration.Redirection login_form_service));

    Eliom_registration.Html.register
        ~service:admin_panel_service
        (fun () () ->
            (* Admin panel html here ... *))
);

解决这个问题的正确方法是什么?

谢谢。

1 个答案:

答案 0 :(得分:1)

我不知道你是否找到了解决方案,因为你的问题现在有点老了但是我发现了这个问题:

我使用"注册决定他们想要发送什么的服务"来自https://ocsigen.org/eliom/6.3/manual/server-outputs#redirections

我们的想法是使用Eliom_registration.Any注册您的服务,这允许附加到服务的处理程序通过使用适当的发送功能即时决定要提供的答案类型。

where (@su is null or @su = '' or @su = su)