BSD-3-Clause licensed by Christopher Reichert
Maintained by [email protected]
This version can be pinned in stack with:yesod-auth-basic-0.2.0.0@sha256:776eeafff2228f12a1e70fcb923dc72681d1f63a48c42f8fce763a62655c34e6,1824

Module documentation for 0.2.0.0

Yesod HTTP Basic Authentication

Hackage

HTTP Basic Auth for Yesod applications. Use HTTPS.

Usage

Import Yesod.Auth.Http.Basic, then add this override to your existing YesodAuth instance, where AuthId App = Text:

maybeAuthId = defaultMaybeBasicAuthId checkCredentials defaultAuthSettings

Supply your application’s credential checker. For example:

checkCredentials :: ByteString -> ByteString -> IO Bool
checkCredentials username password =
    pure (username == "user" && password == "secret") -- Example only.

The checker receives decoded bytes unchanged. Usernames must be valid UTF-8 because the authenticated ID is Text; password encoding is up to the checker. Successful and failed results are cached only within the current request.

Protect routes and send a challenge

The helper does not enforce access or send HTTP challenges. Configure these in your application’s Yesod instance (using your own route names):

instance Yesod App where
    authRoute _ = Nothing -- Return 401 instead of redirecting to a login page.

    isAuthorized ProtectedR _ = do
        user <- maybeAuthId
        pure $ maybe AuthenticationRequired (const Authorized) user
    isAuthorized _ _ = pure Authorized

    errorHandler NotAuthenticated = do
        addHeader "WWW-Authenticate" "Basic realm=\"API\", charset=\"UTF-8\""
        defaultErrorHandler NotAuthenticated
    errorHandler err = defaultErrorHandler err

Missing or invalid credentials on ProtectedR produce a 401 response. authRealm is currently reserved; set the challenge’s realm in your handler.

Requests

Let your HTTP client construct the header:

curl --user 'user:secret' https://example.com/protected
Authorization: Basic <base64(username:password)>

Basic is case-insensitive and followed by ASCII spaces. Use standard Base64 with required padding, without quotes or embedded whitespace. Malformed headers are rejected, not repaired. Decoded credentials are not trimmed; colons after the first delimiter remain part of the password.

Changes

Changelog

0.2.0.0

Breaking changes

  • Require GHC 8.10 / base 4.14 or newer.
  • Decode credentials with strict RFC 4648 Base64 validation. Quoted tokens, embedded whitespace, invalid characters, missing required padding, excess padding, and trailing junk are rejected rather than silently repaired.
  • Require ASCII spaces after the case-insensitive Basic scheme. Tabs and nonbreaking spaces are no longer accepted as separators.

Clients should use their HTTP library’s Basic Auth option, or send an unquoted Base64 token. Decoded usernames and passwords are still passed to the checker unchanged; credentials are not trimmed.

Fixes and maintenance

  • Return Nothing for invalid UTF-8 usernames instead of throwing, even if the credential checker accepts those bytes. Passwords remain opaque bytes.
  • Use a newtype for AuthSettings; its realm field remains reserved.
  • Replace placeholder tests with authentication, UTF-8, and request-cache tests.
  • Replace Travis with cached, pedantic GitHub Actions builds for LTS 18.28, LTS 22.38, and LTS 24.65.
  • Simplify README/Haddock usage and Basic challenge examples, remove unused dependencies, and show the callback type directly in the public signature.

Route authorization and HTTP challenges remain application-managed. Successful and failed authentication results remain cached only within each request.