Automate Retry on Expired Auth Token in JavaScript SDK - node.js

The Scenario
A Node.js app uses some third-party SDK that makes authorized calls to an API. The authorization mechanism is an access token to be passed alongside the call, and --- if the token has expired -- a response sent to the client code 401.
What I Would Like to Know
How can augment this SDK so that calls containing an expired token automatically retry the original request, after a valid access taken is returned?
In Other Words,
I'm surprised that the SDK doesn't do this by default. It has methods to get and set tokens. If an access token has been set, it places that in the request, but doesn't handle responses. My code, therefore, is left checking each failed request for 401, and manually fetching, then updating tokens, and -- then -- retrying the original call.
DRY
is what this ain't. While I am displeased the SDK doesn't automate this process, I would not be surprised to learn that such a pattern is common. Have backend Node.js developers encountered something along these lines, and -- if so -- how did you approach a solution?
Finally
Thank you.
PS. I tried extending the SDK as a subclass, and re-casting methods that call the API in a thunk'd iteration. I did not get very far.

Related

Where is google api auth data being stored in node?

So if I use the node he client how is auth information being passed around ?
In the photo frame example it checks form data using the express body parser for a user and is authenticated function call.
But then it also calls api functions and makes requests outside the browser.
Just curious what the process is storing and where and how it’s being passed around.
Obviously the application tells Google what it is with some use of the client ids but is there a token the application has access to as well once OAuth is finished identifying the specific user account and where is that ? And how does the connecting browser keep this between server calls ? The response headers seem empty of anything of that nature. Thanks in advance.

Is this an acceptable approach to refreshing JWTs?

I'm in the process of rebuilding an existing web app, that uses JWTs to manage authentication. I'm still new to JWTs, so I'm learning about how they should work, while, at the same time, trying to understand why the web app's current implementation is the way it is.
The current version's flow is as follows:
When a user successfully logs in or registers, a user object is returned along with a JWT property. This JWT is included in subsequent API calls as an Authorization header.
Every ten minutes, a get request is made to API endpoint /refresh-token.
If successful, the response body contains a success message, and the response header contains an updated Authorization header.
All subsequent ten-minute timed get requests to /refresh-token use the original JWT that was returned in step 1, and so on.
From what I've read so far, this doesn't correlate with any recommended approaches.
Is it safe enough to replicate this flow in the newer version, or is this something I'm better off not replicating?
Edit: I'm working solely on the front-end - the API isn't being updated for a while, so I'm limited to what it currently returns.
I believe this article summarizes the current state of the art: https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/. You usually have two tokens. Access token which is short lived and an refresh token, which lives longer. This way you don't need to call the auth server every x minutes, but you can do it on demand.
I don't know if you need to deal with blacklisting too? I believe blacklisting is easier when you have a separation of access token and refresh token (only refresh token needs to be blacklisted). But I believe you could deal with this problem too, probably in a bit more sophisticated manner.
Having said that. What you have is not wrong. It's hard for me to point out any flaws in the way you are doing besides of what has been pointed out above.

firebase_admin auth.verify_id_token is very slow

I am resolving user data using firebase for auth like so:
from firebase_admin import auth
decoded_token = auth.verify_id_token(client_id_token)
I am initializing my firebase creds with firebase_admin.initialize_app(cred)
Here cliend_id_token is a token that the client sends. However, this takes around 1 second to perform, which seems way too long. One possibility is to use a caching layer above this (lru cache, memcache) but it still seems that it should not fundamentally take so long. Looking at the the signature of verify_id_token there does not seem to be anything that stands out as something that I can pass in:
def verify_id_token(id_token, app=None):
Any thoughts on how to diagnose (or if I am missing something)?
The problem is because that function does an http request in order to have the key to decode the jwt. In addition, because it returns info such as the email of the user, while the jwt contains only the uid as sub field of the decoded jwt, I think that it does another http request under the hood to get the user from the decoded uid.
You should implement your custom decode function, following the docs: https://firebase.google.com/docs/auth/admin/verify-id-tokens
I'm having the same issue. It's about 200ms for me (I'm using fastapi). #EuberDeveloper - glad to hear it's the same on node js - you saved me from testing it out.
I wanted to mention how I got my setup working faster in case anyone would benefit.
I've got Google API gateway with Firebase security defined in the swagger spec in front of a Cloud Run instance. API gateway validates the jwt (as per the swagger spec) and passes on the authorization header to the backend as a renamed header (from memory it's X-FORWARDED-AUTHORIZATION but best to double check). This is pretty fast.
Then in the backend you don't need to validate the id token since it'll already be validated by the time the request gets there. And if you send the UID along in the request to your backend as well as the idtoken in the authorization header, you can fetch users with the UID field you send. This removed that 200ms it was costing me to decode the id token.
Note - if you want to do things like check how old a refresh token is and revoke it for some reason then you'll still need to decode the id token.

Remember Me Token in Nodejs RESTFul API

I'm developing a RestFul Apis for a mobile application (Android App). I'm using 2-Step auth using OTP and remember me token. For the remember me token I'm currently using Remember Me (any other similar strategy npm is welcome). The npm basically sets a unique token to a cookie which the App can use to verify itself. According to documentation in the above NPM, it recommended to re-generate the tokens after every request.
However in the event when the mobile App makes multiple parallel requests, all the parallel request use the same token. This undoubted give an auth error. I guess this is common situation. I wanted to know if there is a standard way to handle this ?
Current Workflow
Mobile App request authentication with a given OTP
Upon successful verification, the App is give a token which is
passed back in a cookie
For calls to protected APIs, the App calls
the API with cookie passed back in the previous step.
The server resets the token in the cookie and sends back the response to the App
Issue with the workflow
The App is successfully logged-in and has a valid cookie.
App makes a call to a protected API /protected_api_1
The server has reset the token in the cookie for the above call but has not yet completed the reponse
App makes a second call /protected_api_2, with the old cookies as the App does not have the new cookie with it.
Auth fails for (3)
Ok, checking your update I think of 3 workarounds for this. Let's say we have 3 actions, (a), (b) and (c) that requires the token to consume the API.
Token Store
With this just I mean a class, file, cookie or object where you can save your current token, and you can update with the new token after an action is completed.
The problem with this solution is that if you make (a), (b) and (c) at the same time with the same token, the first one who finishes would update the store, and the other 2 would fail. You would have run them synchronously or concurrently.
If you want to do it this way, maybe it would be a better idea to have a:
Lock: a boolean variable that indicates that the token is being used and that the current request must wait for the token to execute and update the token.
Queue: just a linked list where you push the requests and they are consumed asynchronously when the lock isn't set. You implement a service in another thread that handles the queue, may in a similar fashion to a reactor pattern.
Grouping The Requests
Let's suppose that your application executes (a), (b) and (c) very often. In that case, it would be a good idea to group them in just one action and execute it on the server with just one callback. This could be complicated in your case because it would require to create new resources or think about your modeling of the problem.
Managing token expiration
I've seen this in some projects. You set a soft expiration for the token, let's say 15 minutes (or even less). After the time has passed, you give the client a new token, before that time you keep the same token. (a), (b) and (c) would run at the same time with the same token. Problems would happen when you run the requests near the expiration time, depending on how long it takes to complete them.
I can't give you more details about implementation because I don't know in what language or framework you are implementing the client, and I've never made an Android Application, but I think it would be a good idea to try one of this ideas or a mix of them. Best wishes.
Original
I don't understand what do you mean by parallel in this context.
Try making a Token Store resource in your app which every parallel request consumes and updates after request is done.
If all requests are sent at the send time, maybe it would be a good idea to group them in just one operation, but that would maybe require API endpoint changes.

Making authenticated requests

I am using form authentication and role based access.
I want to make all the subsequent request as an authentication request using the access token.
I refer Loopback-example-access-control example, but not get a clear idea.
In this example, they pass access token using query string. My question is I want to make all the request as authenticated using access-token without pass query string or header.
Any other alternative way is available?
I need demo application that includes authentication and authorization, except loopback-example-access-control example.
Please help me, I am new to strong loop.
There are only three ways to send data to a server: path/query string, headers, and the request body. Since you don't want to use the query string (which is good, you really shouldn't) and you don't want to use a header (which is the most common and currently the industry standard) then you are left with only the request body. That's not a great choice either, and not supported by default in LoopBack, you would have to code that up yourself.
The right solution here is to use the Authorization header and send the access token in there with each request.
And just to be clear, this really has nothing to do with LoopBack, this is just token-based authentication basics. You must pass the token with each request, that's how the system works, there is no alternative.

Resources