I'm creating flask web site that uses some API to retrieve data.
this API has basic authentication with tokens and each token is valid for X hours.
I'll probably will run this app behind nginx+uwsgi and the configuration will be something like that:
[uwsgi]
# Some other config....
master = true
processes = 2
enable-threads = true
threads = 4
So i'm trying to figure out what the best way to maintain updated Auth Token for my processes and their threads.
a common solution is to use a separate script that updates some memcache or some consul solutions and retrieve the data from there but is seems like a overkill for this specific task...
There is some nice way in flask to run some background thread that updates this token?
(just to be clear its ok if the same server will have couple of auth tokens, like one for each process running....)
Save the token to a db along with the creation time, every now and then check how long it's been and then ask for a new API token if the time has expired. If you are using multiple tokens then specify which token in the db is for what.
If you don't want to use a db then you could write the token and timestamp to a file instead.
Related
Im planning on making an application that has two parts two it:
React native mobile app
Browser web-app for desktop users
I'm trying to plan out how im going to manage the backend authentication for this (Node.js, passport.js). Ideally, I can just have one backend manage it, regardless of which type of client.
Lets say im going to ONLY have google auth (for simplicity). I don't need to hit googles API's for any information (like profile, contacts, etc), I just want them to login with a google account. My understanding so far is that theres two main ways (especially since im using passport.js).
jwt based approach
session based approach
For either approach, my issue arises when it comes to the react native app. Since I'm not able to use the HttpOnly cookie, im not sure how to safely store data. e.g
In the jwt approach, if the server administers an access token and a refresh token, the react native client can just store them both in the same place e.g https://github.com/mcodex/react-native-sensitive-info. Which means the refresh token is just as susceptible as the access token, which defeats the point of a refresh token, so might as well just have the access token be long lived.
In the session based approach, react native can just store the session id some where (like react-native-sensitive-info above), and the same problem arises
My current thoughts on what should be done:
It seems like theres no way of getting around the security issue of storing information in react native, so as of now I feel like im just going to follow the JWT approach, and store the access + refresh token in react-native-sensitive-info. However, this does mean that the login endpoint is going to return the access + refresh token in the body of the request when the User-agent is mobile. When the user agent is web then we should be able to set an httponly cookie. The only thing that I can think of is if there is a malicious request that masks the user agent (is this possible?), and then can receive the access + refresh token in the body and will be able to do whatever with that.
Performance Aside
A session based storage approach seems much simpler overall. Yes it does store state on the backend, but if we did the JWT approach we would have to store peoples refresh tokens somewhere on the backend anyway (If theres ever a scenario where we need to invalidate peoples refresh tokens, e.g on logout or damage prevention).
This way, say we have a sessions table, when a user logs out, or if we want to invalidate sessions, all we have to do is delete rows from that table. In the JWT method, if we want to invalidate a refresh token, we have to have a blocklist table (which will only keep growing in size, since refresh tokens shouldn't expire, but I guess they can be dropped after a long period of time). However, if you have LOTS of users, the sessions table could get large, which could cause performance issues (but you could probably just drop sessions over a certain age)
/Aside
Questions:
Ive noticed mobile applications have NEVER asked me to relogin with OAuth. Does that mean they're constantly using their refresh token whenever the access token expires? If theres no clear way to store that in a secure way in mobile, do they just have super long lasting access tokens?
Is all of this thinking overkill? Is it fine to just store a super long-lasting access-token in react native and just use that all the time? Then when the user presses 'logout' we can drop that from local storage?
Would a third party auth system like auth0 manage all of this for me?
I'll try to share my experiencies in different kinds of app, this way things may get more clear.
Authentication Method
On most of the mobile applications (with web applications) I've worked with long term access tokens on the mobile side, most of applications don't require the user to login each time you open the app. Usually we store the token in a Secure Storage.
In some cases I've worked with a memory database (Redis) to put the user's session it's really fast and you don't need to query your main database each request (this was used for a high availability system, it may be overkill for most usecases)
Some very specific solutions may require more security, this will depend on your product (like banks, and transactions apps or apps the keep sensitive data) in these cases I would recommend you to login the user every time he closes the app or stays inactive for to long. (this kind of solution usually relies on fingerprint/faceId libs)
My personal opinion on this matter is to go with jwt, it's easy to maintain on the server side if you need to change backends and has a more defined pattern to follow, but that's my opinion and if you have high demand or some specific usecase this may change.
Storage
Talking about the storage options, there are some good suggestions on where to save data like tokens in a secure way on the react native docs,a good option I've used sometime would be:
https://github.com/emeraldsanto/react-native-encrypted-storage
but you can see more options and it advantages here:
https://reactnative.dev/docs/security#secure-storage
Third party libs
They usually helps with the basics if your projects has the budget and not a lot of customization on the authentication process, usually if it's a brand new project (on the back and front end) they work well.
Most of them will handle most of the hurdle for you like token renovation but you should mind the price scalability for these kind of approach
Wish success on your project.
I have API for book web library and some of them (i think about 40%) need some of user data to check (for actions like book add, tag add, rate and so on):
Static
Identity (id)
Dynamic (this values can change)
Access level(for some api calls it's 10, for another is 20).
Ban(true or false).
Tokens for patreon api calls.
How can i make it as simple secure and scalable as possible? What is current trends?
For now i know this methods:
1) After login you store all data in DB and set user session in cookies. On request you load data from DB on server side check user session and use DB data to check dynamic values for this api call.
Pros: simple, scalable
Cons: DB load (but maybe it's ok?)
2) After login you give user access token with all data (like JWT) and use it on every request, checking on server side with no need for DB requests.
Pros: simple, scalable, no need for DB calls to check user.
Cons: no way to update/deny token if dynamic values (ban, trust) was changed (or maybe there is a way?). Patreon tokens i can update if patreon request from server got error.
3) After login you store all data in Redis with expire time if not used and set user session in cookies. On request you load data from Redis on server side, check user session and use this Redis data to check dynamic values for this api call.
Pros: fast, no need for DB calls for user check.
Cons: complex, to scale you will need separate shared redis server for user dynamic checks (maybe it's not so much difference if you will just load from db like in example 1?)
I am storing Tokens on Session/Local storage on the client side.The problem I am facing is once a user copies that token and uses it for other logged-in session services it works but it should return invalid token on JWT.varify.
Is there any way to Blacklist/Delete/Expire currently used token once a user has logged out?
There a a few ways to set up a blacklist for that purpose:
1) (Blacklist users in the database) Add a database column isTokenExpired for users and set it to false on a successful login, and true when you want to expire the token (for example when the user changes their password, logs out, or enough time has expired).
The above method will achieve your purpose, but I feel it is an insult to programming. I assume you are using JWT so that the user doesn't have to log in every time, and that you have only 1 server which is doing the authentication and all other server functions. Although JWT was not designed for "sessions", using JWT for this purpose can take load off the database. But if you are then setting and checking another database flag on every user action, you are adding that load again, and you still have all the load associated with the JWT etc, so you might as well just re-auth on every user action.
2) (Blacklist a user/the token in server RAM) When I researched this problem for myself (how to invalidate individual tokens), I found some solutions where the server maintains either a whitelist or blacklist in RAM, so without adding database or file load. This may be a somewhat better solution, but I can't remember the names of any of the libraries that facilitate this. Maybe someone else can mention some of them.
3) Set token to a very short expiry time (For example 60 seconds or 5 minutes) and set up the client to automatically request a new token every (~55 seconds or ~4 minutes 50 seconds). The server would then check and validate the token in the same way I assume you are doing it now, without accessing the database, and would then generate a new token with the same values for all the other fields, but with a new "expiry time" value, and send that token back to the client where it would replace its JWT with this new JWT, and re-start its 5-minute timer. This is a good balance between the other choices, and maintains some of the benefits of using the JWT, but does add some small cost. I think this is a pretty good solution for many applications, but it definitely depends on the specific application, but it is somewhat hacky and definitely not "the right way" to do it.
4) Use JWT + Sessions This is "the right way" to do it. After all my research a long time ago, I realized that JWT's are not designed to be used for maintaining sessions: JWT is only a secure way of representing a claim. Imagine having a large system with tens of millions of users, and you require many servers around the world. You may have 3 authentication servers (in USA, Australia, UK). The user will then send its username and password to an authentication server, where the details will be checked in the database, and if valid it will be sent a JWT. You may then also have 10+ regular servers which handle your API. The client will then make each request to an API server with its JWT. The API server will have a copy of the secret key that was used by the authentication server to generate the JWT, and will validate your claim. Your claim is "I am authenticated". This API server will then generate a session and the client will be "logged in". The JWT may be set to expire after 5 minutes. If the user does not log in within this 5 minutes, they will not be able to log in. If they do, they will be logged in until the API server kicks them out. Whenever something happens that would cause you to want to kick the user, the API server can close the session. Even for a single-server application this is still the right way to do it. JWT are not for sessions, and you (exactly as I did) are starting to notice these seemingly unsolvable problems because you are using JWT for sessions.
Anyway, I recommend 3 or 4, both of these options have a net-positive value for many applications.
1 and 2 seem to make more problems than the benefits they provide.
But of course, it always depends on the application. If you're just making some website on fiverr for $5 then just do whatever, you know what I mean?
If there's a better solution I'd be interested to know too! Just remember that JWT represents a claim, and consider exactly what claim your client is representing.
Answering your first question (where is JWT stored in server Node.js)
JWT tokens are not stored on server side. It is a signature(by a secret key, RFC 7519 ) based authentication system.
So server just verifies the token and if it's verified then it gives access to the user and hence any user having your token can act as you.
For example - you can copy cookies/storage of a logged in facebook user and then go to another browser and set those cookies/storage. You will be logged in as that user for a few.
FYI #safebookverified 3rd way is mostly used. thanks.
How can I create sessions and manage them in Node.js without a framework like express?
I know it would be much easier to use express but I want to know how to do it with node just in case.
Most of the questions that mentions managing sessions in node is using express to do so but I want to know how to do that without express.
As a simple starting point, suppose we starts sessions when a user login and destroy when he logout.
So when a user login, we basically create a unique session-id and store this session-id at some db like redis/mysql at our server, same will be given to client for next subsequent requests. (Note do not store session-id in memory of the server, as if the server restart we will loss this sessions)
So next time whenever a new request come from the client with session-id we will identify the user and serve response on the basis of that session-id.
Whenever user logout, we remove the session-id from our db. Similarly we can add timeout for the session-id.
This is a simple concept, it can be extended as required.
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.