Open krtx opened 8 years ago
Indeed it is planned. We should have something that's based on https://github.com/inhabitedtype/ocaml-session
I've been experimenting with ocaml-session
a bit to see how we can integrate it with Opium. Have to say I find the API a bit confusing. If we integrate it, it would be good to wrap it and try to identify a user-friendly API.
One thing that makes me think we will probably have to build our own solution is that ocaml-session
does not support storing sessions in signed cookies (and is incompatible with it as of now), which is the most important use case IMHO.
Is it not possible to create a a cookie backend for session?
Not at the moment, the types for get
and set
in the backend interface are:
val get : t -> key -> (value * period, error) result
val set : ?expiry:period -> t -> key -> value -> unit
get
takes only the backend instance as an argument, so either we create a new backend for each request, or we make the current request stateful. Neither of wich seems like a good solution.
Similarly, set
should take the current response and return a response instead of ()
.
So, from what I can see, the API of ocaml-session
would have to change its API quite a bit to support signed-cookie.
I would like to see cookie-based session support, too. I tried to implement something simple myself but without luck so far: set a cookie when a form posts correct credentials and later check for the presence of the cookie. I also struggle with composing the app such that some routes require authentication while others don't. It seems that once you have an authentication test in the stack, it affects all routes and not just the one below it.
@lindig I have selective session checking (and selective CSRF token checking) support built as middlewares based on this: https://github.com/rgrinberg/opium/issues/263#issuecomment-787061404
You can probably do something similar; else I can probably either PR some of these middlewares to Opium, or publish them in their own repo. I have a nice composable chain of these things, something like a nice logger with colors and request ids, followed by session checking (I do check them unconditionally, because I generate pre-sessions for non-logged-in users; the session middleware exposes a function for replacing the session if one of the handlers logs it in). This is followed by routing, with POST routes being strictly filtered by Content-type, which is then followed by CSRF token checking. Forms are loaded into pattern-matching-friendly values.
I even have middlewares for choosing the UI language, any path prefix, and the whole URL structure.
Overall, Opium middlewares seem to compose very well.
Thanks. I have solved the problem of requiring authentication only for some routes but my session support is primitive as it relies on simple tokens. My main
function looks like this:
let main () =
Logs.set_reporter (Logs_fmt.reporter ());
Logs.set_level (Some Logs.Info);
O.App.empty
|> O.App.middleware O.Middleware.logger
|> O.App.post "/login" @@ login ~succ:reset ~fail:reset
|> O.App.post "/upload" @@ auth ~succ:upload ~fail:reset
|> O.App.get "/logout" @@ logout reset
|> O.App.get "/" @@ auth ~succ:index1 ~fail:index0
|> O.App.cmd_name "Quad" |> O.App.run_command
Is it planned to support session?