packages feed

hoauth2-tutorial 0.9.0 → 0.9.1

raw patch · 3 files changed

+63/−63 lines, 3 filesdep ~containers

Dependency ranges changed: containers

Files

hoauth2-tutorial.cabal view
@@ -1,9 +1,9 @@ cabal-version: 2.4 name:          hoauth2-tutorial-version:       0.9.0+version:       0.9.1 synopsis:      Tutorial for using hoauth2 description:-  Tutorial to demostrate how to use hoauth2 to implement OAuth2 flow in an web Application.+  Tutorial demonstrating how to use hoauth2 to implement an OAuth2 flow in a web application.  homepage:      https://github.com/freizl/hoauth2 license:       MIT@@ -18,7 +18,7 @@  source-repository head   type:     git-  location: git://github.com/freizl/hoauth2.git+  location: https://github.com/freizl/hoauth2.git  common common   hs-source-dirs:   src@@ -46,4 +46,4 @@ executable hoauth2-experiment-tutorial   import:        common   main-is:       HOAuth2ExperimentTutorial.hs-  build-depends: containers >=0.6 && <0.8+  build-depends: containers >=0.6 && <0.9
src/HOAuth2ExperimentTutorial.hs view
@@ -4,16 +4,16 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} --- | If you're hurry, go check source code directly.+-- | If you're in a hurry, check the source code directly. -- -- = Configure your Identity Provider and Application ----- Pick which OAuth2 provider you'd to use, e.g. Google, Github, Auth0 etc.--- Pretty much all standard OAuth2 provider has developer portal to guide developer to use oauth2 flow.--- So read it through if you're unfamiliar OAuth2 before.--- Often time, those documents will guide you how to create an Application which has credentials+-- Pick which OAuth2 provider you'd like to use, e.g. Google, GitHub, Auth0 etc.+-- Pretty much all standard OAuth2 providers have developer portals to guide developers on using the OAuth2 flow.+-- Read them through if you have not used OAuth2 before.+-- Often, those documents will guide you through how to create an Application that has credentials -- (e.g. @client_id@ and @client_secret@ for a web application), which will be used to authenticate your--- service (replying party) with server.+-- service (relying party) with the server. -- -- For some OIDC providers, you may even be able to find out those URLs from a well-known endpoint. --@@ -21,7 +21,7 @@ -- https:\/\/BASE_DOMAIN\/.well-known\/openid-configuration -- @ ----- In this tutorial, I choose Auth0. This is the API Docs <https://auth0.com/docs/api>.+-- In this tutorial, I use Auth0. Here are the API docs: <https://auth0.com/docs/api>. -- -- Define a @Idp@ and an Application --@@ -39,10 +39,10 @@ -- -- To generate an authorization URL, call method `mkAuthorizationRequest`. ----- That method will also automatically append following query parameter to the authorization url.+-- That method will also automatically append the following query parameters to the authorization URL. -- -- @--- client_id = 'xxx'        -- client id of your Application credential you got previously+-- client_id = 'xxx'        -- client id from your application credentials you got previously -- response_type = 'code'   -- must be for authorization request -- redirect_uri = 'xxx'     -- where does the server (provider) send back the authorization code. -- @@@ -57,9 +57,9 @@ -- -- = Redirect user to the Authorization URL ----- Now you need to have your user to navigate to that URL to kick off OAuth flow.+-- Now you need to have your user navigate to that URL to kick off the OAuth flow. ----- There are different ways to redirect user to this authorization URL.+-- There are different ways to redirect users to this authorization URL. -- -- e.g. --@@ -76,28 +76,28 @@ -- -- = Obtain Access Token ----- When user navigates to authorization URL, user will be prompt for login against the OAuth provider.+-- When a user navigates to the authorization URL, the user will be prompted to log in with the OAuth provider. ----- After an successful login there, user will be redirect back to your Application's @redirect_uri@+-- After a successful login there, the user will be redirected back to your application's @redirect_uri@ -- with @code@ in the query parameter. -- -- With this @code@, we could exchange for an Access Token. ----- Also you'd better to validate the @state@ is exactly what you pass in the authorization URL.--- OAuth2 provider expects to send the exact @state@ back in the redirect request.+-- Also, you should validate that @state@ is exactly what you pass in the authorization URL.+-- The OAuth2 provider is expected to send the exact @state@ back in the redirect request. -- -- To obtain an Access Token, you could call `conduitTokenRequest`,--- which essentially takes the authorization @code@, make request to OAuth2 provider's @/token@ endpoint+-- which essentially takes the authorization @code@ and makes a request to the OAuth2 provider's @/token@ endpoint -- to get an Access Token. ----- `conduitTokenRequest` returns @ExceptT (OAuth2Error Errors) m OAuth2Token@--- However Scotty, which is web framework I used to build this tutorial,--- requires error as Text hence it is transformed with @oauth2ErrorToText@+-- `conduitTokenRequest` returns @ExceptT TokenResponseError m TokenResponse@+-- However, Scotty, which is the web framework used in this tutorial,+-- requires errors as Text, so they are transformed with @oauth2ErrorToText@ ----- Once we got the `OAuth2Token` (which actually deserves an better name like @TokenResponse@),--- we could get the actual `accessToken` of out it, use which to make API requests to resource server (often time same as the authorization server)+-- Once we get the `TokenResponse`,+-- we can get the actual `accessToken` out of it and use it to make API requests to the resource server (often the same as the authorization server) ----- "Network.OAuth.OAuth2.HttpClient" provides a few handy method to send such API request.+-- "Network.OAuth2.HttpClient" provides a few handy methods to send such API requests. -- For instance, -- -- @@@ -105,14 +105,14 @@ -- authPostJSON  -- Similar but does POST request -- @ ----- In this tutorial, it makes request to @/userinfo@ endpoint to fetch Auth0 user information--- so application knows who did the authorize.+-- In this tutorial, it makes a request to the @/userinfo@ endpoint to fetch Auth0 user information+-- so the application knows who authorized. -- -- = The end ----- That's it! Congratulations make thus far!+-- That's it! Congratulations for making it this far! ----- If you're interested more of OAuth2, keep reading on <https://www.oauth.com/>,+-- If you're interested in learning more about OAuth2, keep reading at <https://www.oauth.com/>, -- which provides a nice guide regarding what is OAuth2 and various use cases. module Main where @@ -169,7 +169,7 @@ auth0DemoApp :: IdpApplication "auth0" AuthorizationCodeApplication auth0DemoApp = IdpApplication {idp = auth0, application = authCodeApp} --- | You'll need to find out an better way to create @state@+-- | You'll need to find a better way to create @state@ -- which is recommended in <https://www.rfc-editor.org/rfc/rfc6749#section-10.12> randomStateValue :: AuthorizeState randomStateValue = "random-state-to-prevent-csrf"@@ -283,7 +283,7 @@   Either TL.Text TL.Text paramValue key params =   case val of-    [] -> Left ("No value found for param: " <> key)+    [] -> Left ("No value found for parameter: " <> key)     (x : _) -> Right x   where     val = snd <$> filter (hasParam key) params@@ -297,4 +297,4 @@   either Scotty.raise pure result  oauth2ErrorToText :: TokenResponseError -> TL.Text-oauth2ErrorToText e = TL.pack $ "Unable fetch access token. error detail: " ++ show e+oauth2ErrorToText e = TL.pack $ "Unable to fetch access token. Error detail: " ++ show e
src/HOAuth2Tutorial.hs view
@@ -3,16 +3,16 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} --- | If you're hurry, go check source code directly.+-- | If you're in a hurry, go check source code directly. -- -- = Configure your OAuth2 provider ----- Pick which OAuth2 provider you'd to use, e.g. Google, Github, Auth0 etc.--- Pretty much all standard OAuth2 provider has developer portal to guide developer to use oauth2 flow.--- So read it through if you're unfamiliar OAuth2 before.--- Often time, those documents will guide you how to create an Application which has credentials+-- Pick which OAuth2 provider you'd like to use, e.g. Google, GitHub, Auth0 etc.+-- Pretty much all standard OAuth2 providers have a developer portal to guide developers on using the OAuth2 flow.+-- So read it through if you have not used OAuth2 before.+-- Often times, those documents will guide you through how to create an application that has credentials -- (e.g. @client_id@ and @client_secret@ for a web application), which will be used to authenticate your--- service (replying party) with server.+-- service (relying party) with the server. -- -- For some OIDC providers, you may even be able to find out those URLs from a well-known endpoint. --@@ -20,8 +20,8 @@ -- https:\/\/BASE_DOMAIN\/.well-known\/openid-configuration -- @ ----- In this tutorial, I choose Auth0, which is one of existing OAuth2/OIDC Providers in the market.--- This is the API Docs <https://auth0.com/docs/api>+-- In this tutorial, I use Auth0, which is one of the OAuth2/OIDC providers in the market.+-- Here are the API docs: <https://auth0.com/docs/api> -- -- = Generate Authorization URL. --@@ -30,10 +30,10 @@ -- To generate an authorization URL, call method `authorizationUrl`, then call `appendQueryParams` to -- append additional query parameters, e.g. @state@, @scope@ etc. ----- That method will also automatically append following query parameter to the authorization url.+-- That method will also automatically append the following query parameters to the authorization URL. -- -- @--- client_id = 'xxx'        -- client id of your Application credential you got previously+-- client_id = 'xxx'        -- client id of your Application credentials you got previously -- response_type = 'code'   -- must be for authorization request -- redirect_uri = 'xxx'     -- where does the server (provider) send back the authorization code. -- @@@ -48,9 +48,9 @@ -- -- = Redirect user to the Authorization URL ----- Now you need to have your user to navigate to that URL to kick off OAuth flow.+-- Now you need to have your user navigate to that URL to kick off OAuth flow. ----- There are different ways to redirect user to the authorization URL.+-- There are different ways to redirect users to the authorization URL. -- -- e.g. --@@ -65,28 +65,28 @@ -- -- = Obtain Access Token ----- When user navigates to 'authorizeUrl', user will be prompt for login against the OAuth provider.+-- When a user navigates to 'authorizeUrl', the user will be prompted to log in against the OAuth provider. ----- After an successful login there, user will be redirect back to your Application's @redirect_uri@+-- After a successful login there, the user will be redirected back to your Application's @redirect_uri@ -- with @code@ in the query parameter. -- -- With this @code@, we could exchange for an Access Token. ----- Also you'd better to validate the @state@ is exactly what you pass in the 'authorizeUrl'.+-- Also, you should validate the @state@ is exactly what you pass in the 'authorizeUrl'. -- OAuth2 provider expects to send the exact @state@ back in the redirect request. -- -- To obtain an Access Token, you could call 'fetchAccessToken',--- which essentially takes the authorization @code@, make request to OAuth2 provider's @/token@ endpoint--- to get an Access Token, plus some other information (see details at 'OAuth2Token').+-- which essentially takes the authorization @code@ and makes a request to OAuth2 provider's @/token@ endpoint+-- to get an Access Token, plus some other information (see details at 'TokenResponse'). ----- 'fetchAccessToken' returns @ExceptT (OAuth2Error Errors) m OAuth2Token@--- However Scotty, which is web framework I used to build this tutorial,--- requires error as Text hence the transform with 'oauth2ErrorToText'+-- 'fetchAccessToken' returns @ExceptT TokenResponseError m TokenResponse@+-- However, Scotty, which is the web framework used in this tutorial,+-- requires errors as Text, hence the transformation with 'oauth2ErrorToText' ----- Once we got the 'OAuth2Token' (which actually deserves an better name like @TokenResponse@),--- we could get the actual 'accessToken' of out it, use which to make API requests to resource server (often time same as the authorization server)+-- Once we get the 'TokenResponse',+-- we could get the actual 'accessToken' out of it, which could be used to make API requests to the resource server (often times the same as the authorization server) ----- "Network.OAuth.OAuth2.HttpClient" provides a few handy method to send such API request.+-- "Network.OAuth2.HttpClient" provides a few handy methods to send such API requests. -- For instance, -- -- @@@ -94,14 +94,14 @@ -- authPostJSON  -- Similar but does POST request -- @ ----- In this tutorial, it makes request to 'auth0UserInfoUri' to fetch Auth0 user information--- so application knows who did the authorize.+-- In this tutorial, it makes a request to 'auth0UserInfoUri' to fetch Auth0 user information+-- so the application knows who did the authorization. -- -- = The end ----- That's it! Congratulations make thus far!+-- That's it! Congratulations for making it this far! ----- If you're interested more of OAuth2, keep reading on <https://www.oauth.com/>,+-- If you're interested in learning more about OAuth2, keep reading at <https://www.oauth.com/>, -- which provides a nice guide regarding what is OAuth2 and various use cases. module Main where @@ -156,7 +156,7 @@     ]     $ authorizationUrl auth0 --- | You'll need to find out an better way to create @state@+-- | You'll need to find a better way to create @state@ -- which is recommended in <https://www.rfc-editor.org/rfc/rfc6749#section-10.12> randomStateValue :: BS.ByteString randomStateValue = "random-state-to-prevent-csrf"@@ -272,7 +272,7 @@   Either TL.Text TL.Text paramValue key params =   case val of-    [] -> Left ("No value found for param: " <> key)+    [] -> Left ("No value found for parameter: " <> key)     (x : _) -> Right x   where     val = snd <$> filter (hasParam key) params@@ -286,4 +286,4 @@   either Scotty.raise pure result  oauth2ErrorToText :: TokenResponseError -> TL.Text-oauth2ErrorToText e = TL.pack $ "Unable fetch access token. error detail: " ++ show e+oauth2ErrorToText e = TL.pack $ "Unable to fetch access token. Error detail: " ++ show e