Skip to content

Commit c22d74c

Browse files
aaron levinjkarni
authored andcommitted
Add basic authentication to tutorial
1 parent 75da1a1 commit c22d74c

File tree

3 files changed

+464
-2
lines changed

3 files changed

+464
-2
lines changed

doc/tutorial/ApiType.lhs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,50 @@ One example for this is if you want to serve a directory of static files along
309309
with the rest of your API. But you can plug in everything that is an
310310
`Application`, e.g. a whole web application written in any of the web
311311
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)