Dans la programmation Web, un modèle courant pour la soumission de formulaires est:
Comment exprimer cela dans Ocsigen?
J'ai lu la documentation, mais je n'ai pas pu comprendre comment accomplir cette tâche simple (et très courante).
Exemple de cas d'utilisation:
Supposons que je dispose d'un formulaire de connexion qui protège contre tout accès non autorisé au panneau d'administration (une page à laquelle seuls les administrateurs doivent accéder). Si l'utilisateur fournit les informations d'identification correctes dans le formulaire de connexion, l'utilisateur doit être redirigé vers le panneau d'administration. Si les informations d'identification sont incorrectes, l'utilisateur doit être redirigé vers le formulaire de connexion. Jusqu'à présent, j'ai implémenté avec succès cette fonctionnalité.
Cependant, je suis perdu lorsqu'il s'agit de mettre en œuvre ce qui suit: si l'utilisateur est déjà connecté et tente d'accéder au formulaire de connexion, l'utilisateur doit être redirigé vers le panneau d'administration. De plus, si l'utilisateur n'est pas connecté et tente d'accéder au panneau d'administration, l'utilisateur doit être redirigé vers le formulaire de connexion.
Voici mon code au point où je suis resté bloqué:
(* 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 ... *))
);
Quelle est la bonne méthode pour résoudre ce problème?
Merci.
Je ne sais pas si vous avez trouvé la solution car votre question est un peu vieille maintenant, mais voici ce que j'ai trouvé:
J'ai utilisé "Services d'enregistrement qui décident de ce qu'ils veulent envoyer" sur https://ocsigen.org/eliom/6.3/manual/server-outputs#redirections
L'idée est d'enregistrer vos services auprès d'Eliom_registration.Any, cela permet au gestionnaire attaché au service de décider à la volée du type de réponse à fournir en utilisant la fonction d'envoi appropriée.
(* 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
let login_panel () = Eliom_content.Html.D.(
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
]]) ()])
)
let admin_panel () = Eliom_content.Html.F.(
Eliom_tools.F.html
~title:"Fake Admin Panel"
(body [h1 [pcdata "Fake Admin Panel"];])
)
(* Some helper functions *)
let admin_credentials ~user_is_admin ~user_is_not_admin =
let%lwt usr = Eliom_reference.get session_username in
if usr = Some username then user_is_admin ()
else user_is_not_admin ()
let send_redirection service =
Eliom_registration.Redirection.send (Eliom_registration.Redirection service)
let send_page page =
Eliom_registration.Html.send page
(* Register Eliom services. *)
let () = Eliom_content.Html.D.(
Eliom_registration.Any.register
~service:login_form_service
(fun () () ->
admin_credentials
~user_is_admin:(fun () -> send_redirection admin_panel_service)
~user_is_not_admin:(fun () -> send_page (login_panel ()))
);
Eliom_registration.Redirection.register
~service:login_service
(fun () (user, pass) ->
if user = username && pass = password then (
let%lwt _ = Eliom_reference.set session_username (Some username) in
Lwt.return (Eliom_registration.Redirection admin_panel_service))
else
Lwt.return (Eliom_registration.Redirection login_form_service));
Eliom_registration.Any.register
~service:admin_panel_service
(fun () () ->
admin_credentials
~user_is_admin:(fun () -> send_page (admin_panel ()))
~user_is_not_admin:(fun () -> send_redirection login_form_service))
)
Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.
En cas d'infraction, veuillez [email protected] Supprimer.
laisse moi dire quelques mots