Skip to content

uliSchuster/servant-auth-rio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Authentication with Servant and RIO

This is a little exercise and experiment to understand how to use the Servant framework for typed web APIs and cookie authentication by means of the Servant.Auth Package, in combination with the ReaderT/IO design pattern as implemented in the RIO Monad.

By default, Servant uses its own Handler monad, which is a wrapper around ExceptT ServerError IO. This is the ExceptT IO anti-pattern, which I want to avoid. The Servant documentation provides functions to hoist a custom monad into Servant's Handler; and example using ReaderT is available here.

As of version 0.18.2, Servant supports HTTP basic authentication and a generic extension mechanism for other authentication schemes. The Servant.Auth Package provides token and cookie-based authentication. When serving a protected API, an authentication function must be provided as server context. When using a custom handler monad, the context must be hoisted together with the custom monad: Instead of hoistServer, Servant provides the function hoistServerWithContext to this end.

In the present minimal example, I came across two problems, with solutions by helpful comunnity members:

  • For a complex API with multiple endpoints combined via Servant's :<|> type combinator, the return type is a combination of the individual endpoint return types. If instead of returning a value the authentication check throws an error, this must also be a combination of errors, one for each endpoint. Servant provides the throwAll helper function (from the ThrowAll type class). With RIO as handler monad, the helper function does not work because RIO does not have an instance of the MonadError typeclass. To alleviate this problem, danidiaz provided the RIOThworAll type class with the rioThrowAll helper, as discussed in this post on StackOverflow.
  • Because of some limitation in the Servant base package (see issue #1267), Servant-Auth currently cannot return headers for a HTTP 204 (No Content) response (see servant-auth issue #177). Authentication requires Cookie and X-CSRF headers, though. A workaround suggested in the above issue is to provide an instance for the particular NoContent verbs needed, as discussed in this StackOverflow post.

Resources

In putting together the example, I examined the following blog posts, code snippets, and documentation:

About

Servant cookie authentication with RIO as handler monad.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published