Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session support #60

Open
krtx opened this issue Jun 30, 2016 · 7 comments
Open

Session support #60

krtx opened this issue Jun 30, 2016 · 7 comments

Comments

@krtx
Copy link

krtx commented Jun 30, 2016

Is it planned to support session?

@rgrinberg
Copy link
Owner

Indeed it is planned. We should have something that's based on https://github.com/inhabitedtype/ocaml-session

@tmattio
Copy link
Collaborator

tmattio commented Nov 13, 2020

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.

@rgrinberg
Copy link
Owner

Is it not possible to create a a cookie backend for session?

@tmattio
Copy link
Collaborator

tmattio commented Nov 16, 2020

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.

@lindig
Copy link

lindig commented Jan 21, 2021

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.

@aantron
Copy link

aantron commented Feb 27, 2021

@lindig I have selective session checking (and selective CSRF token checking) support built as middlewares based on this: #263 (comment)

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.

@lindig
Copy link

lindig commented Feb 27, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants