Skip to content

Commit f742a5c

Browse files
committed
Simplify auth section in apitypes
1 parent 45eba28 commit f742a5c

File tree

1 file changed

+28
-47
lines changed

1 file changed

+28
-47
lines changed

doc/tutorial/ApiType.lhs

Lines changed: 28 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,34 @@ response, you could write it as below:
287287
type 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
292320
Finally, 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
309337
with 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
311339
frameworks 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

0 commit comments

Comments
 (0)