I have a REST API and I'm looking for an easy way to do a secure token-based authentication. Since I've read that protocols like OAuth are very complex, I'd like to implement a simpler way. What are the common approaches? And what about the security of the following procedure?
Is there a massive security problem with this approach? Or is that feasible?
Thanks a lot
The short answer is there is no major security problem with the concept of this approach, but implementation is key, and this is probably my most important point.
What you described is basically a plain old session. The "token" here is just a session id. Web applications have worked this way for ages. There are known high quality implementations that avoid session fixation, weak or insecure session id generation and so on, there is a long list of session management vulnerabilities. If you try to implement it yourself, well, that will not be easy to get it right and secure. So if you intend to do it this way, just use a known good implementation and that's it.
There is a difference though, you want to store your "token" (session id) in "webstorage", which can be one of localStorage, sessionStorage or WebSQL basically. Traditional session management stores session ids in cookies for a good reason - a cookie can be much better protected against cross-site scripting (XSS). If a session cookie is marked httpOnly, Javascript won't be able to access it, it will only be sent back to the same server (origin, actually) by the browser. This is not possible with any other storage, which means if there is an XSS vulnerability in your site (any page on the same origin), user tokens can be stolen. And that is significantly less secure than using an httpOnly cookie.
In modern web applications, this is many times an accepted risk. That happens mainly when you want to send the same token to multiple servers (origins). That would not be possible with an httpOnly cookie. But if your token is stored to a database, you probably don't want to do this anyway for architectural reasons if not else.
Also note though that this design, sending the token in headers prevents cross-site request forgery (CSRF) almost by default. So the upside is you don't have to care (much) about CSRF, but this comes at the cost of XSS impact, and that outweighs this benefit in most cases.
As a final note, this is not a security thing, but using your design, your API will be stateful, it will store a state for each client. This is not very good, because as you correctly said, you will have to go to the database to check the token for every single request (or you can go down the rabbithole of caching and similar sources of complexity). And then imagine what happens if your service needs to be load-balanced, running on multiple servers, with several instances of database replicas. Modern API design therefore aims to be stateless - no state stored for clients. And that's where (real) token authentication shines, the tokens don't need to be stored to databases, they are authentic by themselves. That's where token-based authentication really makes sense, and not in simple scenarios, where a plain session id would also do, and would be more secure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With