In this case, you would have to use rotating refresh tokens (https://tools.ietf.org/html/rfc6819#section-5.2.2.3). They are essentially one-time use refresh tokens and help in token theft detection. So essentially, both, the access and the refresh token keep changing. You can learn more about implementation details and its benefits here: https://supertokens.io/blog/the-best-way-to-securely-manage-...
HN user
rp2684
This problem will also exist if an opaque token is used instead of a JWT (as long as a refresh token is being used). Now you may argue that we don't need to use refresh tokens because that's complex, however, in that case, you are severely compromising on user security. See this please: https://supertokens.io/blog/all-you-need-to-know-about-user-...
A way to solve this issue would be to synchronise around refresh API calls. This way, parallel refresh calls will never happen, and in fact, you need to even do the 2nd onwards refresh call. The trickiest part here is to also lock across tabs, since the user could have several tabs of your website open and all of them running in parallel.
This is exactly what SuperTokens.io does in their website SDK. As a user, you don't need to worry about this and can simply make your fetch / axios calls as usual.
One very important aspect of authentication is session management. Doing this wrong (or naively), can have catastrophic effects for your app!!
Let me provide an example: It's common knowledge that JWTs are very common. A lot of people who use JWTs, implement them as access tokens for their APIs. JWTs also require a shared secret key - what if this is stolen? Then an attacker can use that to hijack any user's account very trivially, and you may not even realise that it's happened! This is far worse than anyone getting hold of hashed passwords from your database.
That being said, I use the following flow for session management: - User logs in, the backend issues a short-lived (~1 hour) JWT and a long-lived refresh token and sends them to the frontend. - The frontend sends the JWT for each API call while it's still valid - In the event that the JWT has expired, the frontend should then use the refresh token to get a new JWT AND a new refresh token (rotating refresh token - see https://tools.ietf.org/html/rfc6749#section-10.4) - If the refresh token expires, then the user has to login again.
While this sounds quite straightforward, the key here is to use rotating refresh tokens - that's what actually makes it fare more secure than just using simple refresh tokens (i'd argue that it's almost the same level of security as just using a long lived access token)
Some of the benefits of this approach: - You can detect token theft! If an attacker gets hold of the refresh / access token, because they keep changing, you can detect if an old token is used which is a strong singal of theft (see the RFC link above) - You can change the JWT secret key without logging any users out: Once you change the key, all JWTs are instantly invalidated. But then your frontend client can simply use its refresh token to get a new access token signed with the new signing key (along with a new refresh token). - Allow your users to be logged in for however long you want without compromising security.
Some implementation gotchas: - When changing the refresh token, be sure to not invalidate the older token unless your backend is sure that the frontend has received the new token. This can be confirmed by the frontend using the new access / refresh token. This is important since if not done, and if the user is in a bad networked area, it can lead to them being logged out. - See this blog and specifically this race condition: https://medium.com/hackernoon/the-best-way-to-securely-manag...
If you do not want to implement this on your own, you can also check out https://supertokens.io - It provides an end-to-end implementation of the above taking care of all race conditions and network failure issues. It also prevents other common web attacks which are on the OWASP top 10 list.
-----------------------
In terms of user authentication for the login part, I prefer using a no-password method - email or SMS OTP. The reason for this is that I do not have to care about managing user passwords (though that's not too difficult), I do not have to build forgot password flows, and most importantly, users don't have to remember yet another password.
I also only allow 3 attempts for OTPs per OTP. So after sending the OTP, if a user fails to input the correct one 3 times, then I revoke the old OTP and send a new one (this is so that someone can't simply brute force their way into an account). If the user login is successful, then I revoke all OTPs for that user. If the user clicks on sending the OTP again, then I send a different OTP (but the old one is still valid). This allows me to have a an OTP timeout of say 1 hour - which is more than enough!
According to me, this coupled with the above session management flow, is perfect!
Cheers! Glad to help. If you want to discuss your idea specifically, you can DM me on reddit: @ilovefunctions
I'm not sure what you mean by tools. But I go about structuring my ideas in the following way (at least for software related ideas.): First, I do secondary research about the idea. It's extremely rare that you have a completely unique idea.. And even if that is true, there has got to be some very close existing product/service to it. So I learn as much as I possibly can about them. During my research, I usually go about answering a few key questions: - Why hasn't anyone done <your idea> yet? - Why is it a good time now to do it? (this is perhaps one of the most important) - If someone is doing this, how can you differentiate yourself from them? By region/features/target audience etc..?
Once those are HONESTLY answered, you should start looking at your idea in as much detail as you possibly can. Don't assume things will work out or that you will figure it out later.. Concretely, what I do is answer the following things: - How will I get my first 10 users/customers? - Out of these 10, the first one to "test" your product/service out, what is their ideal experience? (and then think backwards as to how you can give them that.. non scalable method is fine initially.) - What about the 2nd user? the 3rd user? will the 3rd user benefit in any way because there were already 2 other people before them to use the product.. (network effect)? - Why will the 1st user stick to your product after their first ideal experience? Remember, that most people dont care much about most things... You have to work through things to keep the first user onboard. - Why will the other users out of these 10 stick to your product/service? - How will these 10 users cause other's to use your product? (word of mouth is the best form of growth.) - Once you reach the initial steady state of the product (a point where initial automatic growth stops, current users are happy), what does that look like? And how will you grow from there? (The what does that look like is very important. How will you grow from there is something that can be answered a little later too.. as most ideas never reach that anyways). - Eventually, what is your plan? And if you are doing this for profit, how will that plan allow you to make "enough" money? Again, you should have some idea of this. It doesnt need to be proven/super concrete, but the clearer this is in your mind, the better. Having no idea of this is not good, but you are probably wrong if you are super confident since most ideas evolve quite a bit.
The above is the ideation phase. There are probably tons of things that are missing from the above, but I think the ones above are quite important to answer. In the above, I assume you already know that there is proven demand or there will be demand for your product/idea once people see it.
About the execution phase: - Start with "drawing" what your product/service would be like. - Find a way to get as many people to see it/understand it and give you feedback.. ideally when you, approach someone with it, try and see from their point of view. Try and turn your pitch very specific to them, their problem (which your idea addresses). - The feedback process will most likely change your idea/initial design. It may even end up in you not believing in your idea anymore. This will be a tricky situation to be in. - If you do end up "passing" the above, then you most likely will have a concrete product/service to build. - The actual building varies a lot based on ideas.. so I am not going to comment on that here. - But ideally, while you are building, get as many people interesting in it.. Create maybe a mailing list of people who will be willing to try it out once you are ready. Do whatever, but try and get your initial set of users interested and waiting for you to launch. This will not only boost your confidence, but it will also teach you lots about how difficult it will be to "sell" our product once you have finally made it.
I hope the above helps you.. these are just my thoughts from my personal experiences :) Execution is everything... and it is super hard. You need to really believe in what you are making in order for it to work out.. All the best!!