git.iko.soy/typeable/servant
on master help sign in
Simplify auth section in apitypes
commitf742a5c4c83c66c66ccd1bc36417dbbf82967b12 authorJulian K. Arni <jkarni@gmail.com> dateSat 19 Mar 2016, 17:44 (11 years ago) parent45eba28
1 file changed+28−47
doc/tutorial/ApiType.lhs+28−47
doc/tutorial/ApiType.lhs+28−47
@@ -287,6 +287,34 @@ response, you could write it as below:
287287type UserAPI10 = "users" :> Get '[JSON] (Headers '[Header "User-Count" Integer] [User])
288288```
289289
290+### Basic Authentication
291+
292+Once you've established the basic routes and semantics of your API, it's time
293+to consider protecting parts of it. Authentication and authorization are broad
294+and nuanced topics; as servant began to explore this space we started small
295+with one of HTTP's earliest authentication schemes: [Basic
296+Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication).
297+
298+When protecting endpoints with basic authentication, we need to specify two items:
299+
300+1. The **realm** of authentication as per the Basic Authentictaion spec.
301+2. The datatype returned by the server after authentication is verified. This
302+ is usually a `User` or `Customer` type datatype.
303+
304+With those two items in mind, *servant* provides the following combinator:
305+
306+``` haskell ignore
307+data BasicAuth (realm :: Symbol) (userData :: *)
308+```
309+
310+Which is used like so:
311+
312+``` haskell
313+type ProtectedAPI12
314+ = UserAPI -- this is public
315+ :<|> BasicAuth "my-real" User :> UserAPI2 -- this is protected by auth
316+```
317+
290318### Interoperability with `wai`: `Raw`
291319
292320Finally, we also include a combinator named `Raw` that provides an escape hatch
@@ -309,50 +337,3 @@ One example for this is if you want to serve a directory of static files along
309337with the rest of your API. But you can plug in everything that is an
310338`Application`, e.g. a whole web application written in any of the web
311339frameworks that support `wai`.
312−
313−### Basic Authentication
314−
315−Once you've established the basic routes and semantics of your API, it's time to consider protecting parts of it. Authentication and authorization are broad and nuanced topics; as servant began to explore this space we started small with one of HTTP's earliest authentication schemes: [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication).
316−
317−When protecting endpoints with basic authentication, we need to specify two items:
318−
319−1. The **realm** of authentication as per the Basic Authentictaion spec.
320−2. The datatype returned by the server after authentication is verified. This is usually a `User` or `Customer` type datatype.
321−
322−With those two items in mind, *servant* provides the following combinator:
323−
324−``` haskell ignore
325−data BasicAuth (realm :: Symbol) (userData :: *)
326−```
327−
328−You can use this combinator to protect an API as follows:
329−
330−``` haskell
331−-- | Simple data type for our weather api
332−data WeatherData =
333− WeatherData { temp :: Double
334− , wind :: Int
335− } deriving (Eq, FromJSON, Generic, Ord, ToJSON)
336−
337−-- | The user data returned after basic authentication
338−data User =
339− User { username :: String
340− , city :: String
341− , state :: String
342− , country :: String
343− } deriving (Eq, FromJSON, Generic, Ord, ToJSON)
344−
345−-- | parts of the API open to the public (no authentication required)
346−type PublicAPI12 = "public" :> "weather" :> Get '[JSON] WeatherData
347−
348−-- | parts of the API protected by basic authentication
349−type PrivatePAI12 = "private" :> "weather"
350− :> Capture "city" String
351− :> ReqBody '[JSON] WeatherData
352− :> Post '[JSON] ()
353− :<|> "private" :> "account"
354− :> Get '[PlainText] String
355−
356−-- | Our full Weather API, private API protected by basic authentication.
357−type ProtectedAPI12 = PublicAPI12
358− :<|> BasicAuth "weather" User :> PrivateAPI12