firebase_admin auth.verify_id_token is very slow - python-3.x

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.

Related

Automate Retry on Expired Auth Token in JavaScript SDK

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.

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.

Keep temporary data until send response - Nodejs

I'm working on express server application and there are bunch of api endpoints that I configured. Almost all create and update requests, I need to store requested user's userId in order to keep log. I created a middleware function that verify user JWT access token and retrieve userId from access token payload. In my current situation, I add user info as req.body.loggedUser in req body. I think this is not a good thing to do. I do it like,
req.body.loggedUser = accessTokenPayload.user[0];
This works fine in every POST request. But I need to do it in right way. And also this method cannot use in GET requests. If nodejs can keep temporary variable until a request done its process I can keep log on GET requests also. So all I need to do is keep user info as temporary data until request process done. How I can do it.
Just add it to the req variable:
req.loggedUser = accessTokenPayload.user[0]
This works in GET requests as well

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.

XSS Protection in Express Apps

I am developing an express app which serves as a REST api with web client and may be future mobile clients. I am using a Oauth 2.0 token authentication for both clients. This gives a good deal of security against CSRF. I want to know How to provide security against XSS.
*I made the tokens validity period very less, requiring the client to request with refresh_tokens and other client details for access_tokens. This makes it a bit safe but not entirely*.
I am concerned with the with client_id and client_secret being stolen since its present in the front-end javascript code and it being used by other client to validate. I am thinking of using a JWT for the client authentication, will this be helpful?
Data Sanitisation is another which I am confused about. There are modules like validator, express-validator which give regex validation. According to this blog post JSON Schema validations are fast. In the REST Api JSON will used for data exchange so I was wandering why can't I use modules like tv4 or any other JSON Schema validators for data validations?? I am not asking for suggestions to use what, I just want to know the basic difference in the kind of validations each provide and specially from a point of view of XSS protection and sanitisation.
So you have three separate questions here:
1) How to protect against XSS: As long as you use JSON to share data between the client & server and use standard libraries/methods for encoding/decoding JSON, you are mostly protected. After this, you only need to worry about DOM Based XSS, which is harder to be protected. But basically you need to be careful for not using any user supplied input that can be interpreted as anything other than "string" you intended. (please visit https://www.owasp.org/index.php/DOM_Based_XSS for more information)
2) client_id and client_secret being stolen: This does not seem to be possible in the way you require. In your scenario (where you distribute clientid&secret in javascript code) there is no way on server side to know whether the request is coming from your client or a fake one.
3) Data Sanitisation: I see two levels of sanitisation in the libraries you & blogpost mentioned. validator or express-validator is mostly used to validate individual data fields. Whereas others can validate a JSON object structure in addition to what "validator" does. If you require all exchanged data is in JSON format (as suggested for XSS protection as well) then you can use json object validators like tv4. (the only drawback of tv4 seems to be allowing latest json spec, which should not be a problem for you)
BTW: It would be easier if you specified your client application is purely client-side javascript (angularjs). I could not understand your question until I found this info in comments.
I have developed Restful Authentication System same as your case with NodeJS, MongoDB, ExpressJS in order to provide flexible authentication system for multiple clients like web, mobile. Let me summarize you the important points.
I have used html5 localstorage to keep user token after first time login by using login form. When user click login button, username and password sent to server and validated. After successfull validation, unique access token sent to client and stroed in local sotrage. If you have vulnerability on your client application, anyone can get your access token and make request by using your token. In order to prevent this, you need to use ssl connection for your app. This problem does not exists only restful auth systems, this can be happen in server side session storage. Let me explain this. I am using PHP for session. When user logs in, user session saved in to temp file on server and that session id sent to client browser. Somehow, if I can get that id, I can make request with header that contains someone's session id. When you compare, restful auth seems more flexible to me. I suggest you to ;
Use SSL connection prevent your access_token from to be stolen
Generate access token with powerfull encryption methods(SHA-256)
Small expire time for access_token the better
Implement a middleware for token validation for backend service usage. I mean make your requests like;
/use/update/{userid}
with custom headers contains your user token.
Design 5 attempt failed system for your backend. If user cannot success at 5 time try, this means someone tries to send random tokens in order to get in to system. Detect and block that IP
You can also deny requests other than browser clients.
Those are the informations that I have learnt while implementing the project.

Resources