Search code examples
resthttpauthenticationbasic-authenticationstateless

Token-based REST API Authentication


I have a mobile app backed up by a lightweight Node.js API. I've recently started exploring integrating a third-party API service that uses token-based authentication. This API is designed to be called exclusively from my server-side Node.js code since calling it directly from my mobile app would expose my sensitive username/password info. Other similar APIs that can only be called server-side (Stripe, for instance) have required authentication with a secret key that is passed in with every request. This approach makes more sense to me since you don't really think of a server "logging in" to another API.

So, here are my questions about accessing a token-based API:

  1. What is the best approach to making calls to this API? The token has a lifetime of 1 hour. Should I 1) persist the token in a database and, for each request, pull the token from the database, check that it is still valid then make the request to the third-party API? Or, 2) request a new token every time I need to make a request to the API?

  2. What is the benefit of using token based authentication? Since there isn't a concept of logging in and no state needs to be maintained between requests, wouldn't it be easier to use a simple secret key with basic auth?


Solution

  • I'm going to start with #2:

    What is the benefit of using token based authentication? Since there isn't a concept of logging in and no state needs to be maintained between requests, wouldn't it be easier to use a simple secret key with basic auth?

    A basic auth username and password:

    1. Is also a token.
    2. Does not actually 'log you in'. It's stateless in the same way, because the username and password get passed with every request.

    So the difference between the token you're describing and a password really in this case is about the lifetime of the token. It sounds like you probably actually have 2 tokens. One to do requests (access token) and another to request new access tokens if they expired (refresh token).

    Why do this? One idea is that the refresh token is the most dangerous one, because if an access token leaks somehow, it will only be valid for a limited amount of time. By separating these you're basically decreasing the number of potential attack vectors. In a world where everything is secure, this might make no real difference, but we don't live in this world.

    Access tokens can leak into logs, or accidentally get exposed through other means. The chance of a refresh token to be exposed is just lower.

    Some API's also turn the access token in some signed json payload (jwt), so they don't need to check their data-stores for validity. These services might expire refresh tokens in case of security changes (new password, intrusion detection) but not expire the access token.

    But yea it's a bit of a hairy subject. There's no clear attack vector that gets prevented by creating two tokens, but it's defense in depth.