simonh1000/elm-jwt/4.0.1

NOTE: this package is not compatible with Elm 0.19.1

Jwt

Helper functions for working with Jwt tokens and authenticated CRUD APIs.

This package provides functions for reading tokens, and for using them to make authenticated Http requests.

Token reading

decodeToken : Decoder a -> String -> Result JwtError a

decodeToken parses the token, checking that it meets the Jwt standards.

decodeToken dec token

In the event of success, decodeToken returns an Elm record structure using the JSON Decoder.

isExpired : Time -> String -> Result JwtError Bool

Checks whether a token has expired, and returns True or False, or any error that occurred while decoding the token.

Note: This function assumes that the expiry was set in seconds and thus multiplies by 1000 to compare with Javascript time (in milliseconds). You may need to write a custom version if your server-side Jwt library works differently.

Authenticated Http requests

createRequest : String -> String -> String -> Body -> Decoder a -> Request a

createRequest creates a Http.Request with the token added to the headers, and sets the withCredentials field to True.

send : (Result JwtError a -> msg) -> Request a -> Cmd msg

send replaces Http.send. On receipt of a 401 error, it returns a Jwt.Unauthorized.

sendCheckExpired : String -> (Result JwtError a -> msg) -> Request a -> Cmd msg

sendCheckExpired is similar to send but, on receiving a 401, it carries out a further check to determine whether the token has expired.

get : String -> String -> Decoder a -> Request a

get is a replacement for Http.get that returns a Http.Request with the token attached to the headers.

getData : String -> Cmd Msg
getData token =
    Jwt.get token "/api/data" dataDecoder
        |> Jwt.send DataResult
post : String -> String -> Body -> Decoder a -> Request a

post is a replacement for Http.post that returns a Http.Request with the token attached to the headers.

** Note that is important to use jsonBody to ensure that the 'application/json' is added to the headers **

postContent : Token -> Json.Decoder a -> E.Value -> String -> Request a
postContent token dec value url =
    Jwt.post token url (Http.jsonBody value) (phoenixDecoder dec)
        |> Jwt.send ContentResult
put : String -> String -> Body -> Decoder a -> Request a

put returns a PUT Http.Request with the token attached to the headers.

delete : String -> String -> Decoder a -> Request a

delete returns a DELETE Http.Request with the token attached to the headers.

JwtErrors and Http.Error handling

= HttpError Error
| Unauthorized
| TokenExpired
| TokenNotExpired
| TokenProcessingError String
| TokenDecodeError String

The following errors are modeled

  • Any Http.Error, other than a 401
  • 401 (Unauthorized), due either to token expiry or e.g. inadequate permissions
  • issues with processing (e.g. base 64 decoding) the token, and
  • problems decoding the json data within the content of the token
promote401 : Error -> JwtError

Examines a 401 Unauthorized reponse, and converts the error to TokenExpired when that is the case.

getAuth : String -> String -> Json.Decoder a -> Task Never (Result JwtError a)
getAuth token url dec =
    createRequest "GET" token url Http.emptyBody dec
    |> toTask
    |> Task.map Result.Ok
    |> Task.onError (promote401 token)
handleError : String -> Error -> Task Never JwtError

Takes an Http.Error. If it is a 401 then it checks for expirey.

checkTokenExpirey : String -> Task Never JwtError

Checks a token for expirey.

Logging in

authenticate : String -> Decoder a -> Value -> Request a

authenticate creates an Http.Request based on login credentials.

submitCredentials : Model -> Cmd Msg
submitCredentials model =
    E.object
        [ ("username", E.string model.uname)
        , ("password", E.string model.pword)
        ]
    |> authenticateRequest "/sessions" tokenStringDecoder