OAuth2 Refresh token and Http Request

#1

When using OAuth2, my token expire in 1hr. I have a REFRESH_TOKEN to refresh the user token without running login flow again.

In Elm, is it possible to implement the refresh token flow as follow in http 2.0 package?

send API request

if success, return the cmd with success

if failed with 401
|> send refresh token request
|> send API request again with new token
|> return cmd batch [storeNewToken, apiDataSuccess]

if really failed, return cmd with failure

seems that this flow could construct by chaining tasks. but i have no idea how to do.

#2

I’ve not done it myself, but it looks like you would need to create a Http.Resolver to check the status code of the Http.Response from your first request, and another Http.Resolver for the refresh token request. The trick would be to write these resolvers in such a way that they “pass along” the details of the initial request, so that you can then reissue it if you need to.

You can then use Http.task to turn the requests in to tasks and Task.onError to conditionally run the refresh request (which itself should be chained with Task.andThen to rerun the initial request on success). I guess you’d also need some way to avoid infinite loops if for some reason the refresh succeeds but the initial request still fails, so you would maybe also want to pass some kind of retry count along through the custom resolvers.

I’m afraid I don’t have time right now to try this myself, so I may have missed some details. I should point out that if you search the package database there are also some existing OAuth packages for elm out there…

#3

Here is a stackoverflow thread talking about sequencing http with andThen.

I think andThen and e.g. returning a Tuple (token, response) should/could work.

Is this enough for you to try start implementing the flow, and maybe head out with an Ellie example or public repository, if you get stuck?

#4

I have a similar situation against the Drupal REST API. But so far have been unable to come up with something different then handling the error case in my update function, and retrying there.

I received some suggestions here, have a look, as they are similar to your proposal. Haven’t had the time to try them yet.

#5

What I do instead is:

if token timeout is within 1 minute of ending
|> send refresh token request
|> store new token

and

if failed with 401
|> go back to the login screen

By refreshing the token 1 minute ahead of it expiring, the 401 due to expired token is normally never hit.

#6

I am currently using Timer method to refresh the token. However, when the computer goes sleep or inactive, the setTimeout feature of browser doesn’t execute the refresh on time.

I curious about the proper way to handle refresh token workflow in elm.

When in JS, we could

fetchData()
  .catch(/* if 401: refreshToken.then(fetchDataAgain); else: throw err */)
  .then(handleSuccess)
  .catch(handleReallyFail);
#7

I think the short answer is that in case you want to persist new state like new token you need to do so via update function as there is no other way to update the model in tea.

The second question is how would you go about it. And answer to that is that there are different ways with different tradeoffs. I would personally suggest use something you’re familiar with. It can be anything on a scale from the most simple function String -> Model -> Model to state monad. Passing functions in Msgs or avoiding that.

closed #8

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.