simonh1000/elm-jwt/5.2.0

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.

tokenDecoder : Decoder a -> Decoder a

All the token parsing goodness in the form of a Json Decoder

-- decode token from Firebase
let firebaseToken =
    decodeString
        (tokenDecoder Jwt.Decoders.firebase)
        tokenString
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.

checkTokenExpiry : String -> Task Never JwtError

Checks a token for Expiry. Returns expiry or any errors that occurred in decoding.

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.

String
-> String
-> String
-> Body
-> Decoder a
-> { method : String
, headers : List Header
, url : String
, body : Body
, expect : Expect a
, timeout : Maybe Time
, withCredentials : Bool
}

createRequestObject creates the data structure expected by Http.Request. It is broken out here so that users can change the expect part in the event that one of their REST apis does not return Json.

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

Create a PUT request with a token attached to the Authorization header

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

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

Error handlers

= 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
  • token (non-)expiry information
  • 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 the token for expiry.

Logging in

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

authenticate creates an Http.Request based on login credentials. There is very little to this function (and it will be removed in future releases), so feel free to role your own here instead.

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