DEV Community

Cover image for How I Smashed a Bug in a Shared Authentication Library
Daniel Balcarek
Daniel Balcarek Subscriber Community Curator

Posted on

How I Smashed a Bug in a Shared Authentication Library

Summer Bug Smash: Smash Stories ๐Ÿ›๐Ÿ›น

This is a submission for DEV's Summer Bug Smash: Smash Stories powered by Sentry.

This happened a while ago at one of the corporations where I worked.

I was working on a web application as a full-stack developer, so I was responsible for both the frontend and the backend.

Because the corporation was huge, there were several libraries and services shared across multiple teams and maintained by dedicated developers. It was basically open source inside a corporation. ๐Ÿ˜„

And of course, we used some of those libraries and services, because why reinvent the wheel, right?

So, after we released the first version of our web application, an interesting bug appeared.

When a user opened the application in multiple browser tabs, authentication would sometimes randomly break in one of them. Once that happened, the tab could not recover until the user pressed F5 or closed it completely.

Interesting.

As the senior developer on the team, I took the bug and started investigating.

After some time and a lot of attempts, I found that when the frontend tried to refresh the authentication token, it received a 403 Forbidden HTTP response, and the authentication flow broke completely.

So I played around with session storage and local storage in Chrome and tried changing the authentication configuration. It did not help much, but one thing was clear: the bug appeared to be inside the shared frontend authentication library.

Okay.

I collected all the logs and everything I had learned about the bug and went to the frontend team responsible for maintaining the authentication library.

After an hour-long discussion, they concluded that it was not their fault because the backend team maintaining the authentication service was not supposed to return that particular response code.

Yes, the frontend library and the backend authentication service were maintained by completely different teams.

I was not fully convinced, but there were more of them. ๐Ÿ˜

So I collected all the logs again and went to the backend team.

We had another discussion and found that they were returning a valid response code because the frontend authentication library was sending a refresh token that had already been invalidated. The underlying problem was a race condition between multiple tabs. One tab refreshed the token and invalidated the previous refresh token while another tab was still trying to use it.

Okay...

So, once again, I grabbed all the logs and went back to the frontend team.

And in case you are wondering why the two teams did not simply communicate with each other, both teams gave me approximately the same answer:

This is a problem in your application, so your team has to solve it.

Back to the frontend team.

I presented the backend teamโ€™s conclusion, but they were still not convinced.

At that point, I was starting to get a little angry, so I created a single ticket, added both teams to it, and included all the logs, requests, responses, timestamps, and everything else I had collected.

Weeks passed.

Conversations continued in the ticket and in chat.

But the bug resolution still looked far, far away.

So I decided to arrange a meeting for everyone involved.

And finally, something happened.

During the meeting, we agreed that the problem was in the frontend authentication library and that the frontend team would fix it.

Success!

Or so I thought.

Two weeks later, while testers and users were getting increasingly angry because the application randomly failed to refresh authentication tokens, the frontend team came back with their final conclusion:

They were unable to reproduce the problem.

And users should not open the application in multiple tabs.

Until that moment, opening multiple tabs had been considered a perfectly normal user flow...

At that moment, I closed the ticket, completely removed the corporate frontend authentication library from our project, and reimplemented the entire client-side authentication flow directly against the existing corporate authentication service.

The main changes were in the Angular HTTP interceptor and the token refresh flow. I updated the interceptor to handle authentication-related responses, including 403 Forbidden, without leaving the entire tab stuck in a broken state.

I also reworked how refreshed tokens were handled and stored in session storage. Invalidated tokens and failed refresh attempts were now handled explicitly instead of causing the authentication flow to stop completely.

Yes, it took two days and one night. And yes, I took a few ideas from the corporate authentication library, because otherwise it would have taken much longer. ๐Ÿ˜„

But I only have one set of nerves.

And you know what?

From that moment on, it worked like a charm. And whenever another bug appeared, it was fixed immediately because, this time, we actually owned the code.

And that is my Bug Smash story where corporate life can sometimes be slightly ridiculous, and fixing one bug can mean rewriting the entire feature.

Top comments (53)

Collapse
 
thomasburleson profile image
Thomas Burleson •

Did you then convince the FE team use your improved Auth library?

Collapse
 
gramli profile image
Daniel Balcarek •

As far as I remember, no. I closed the ticket, and they didnโ€™t really care about it anymore. As far as I know, they still hadnโ€™t fixed the bug on their side by the time I left the company. ๐Ÿ˜„

Collapse
 
technogamerz profile image
๐“๐ก๐ž ๐‹๐š๐ณ๐ฒ ๐†๐ข๐ซ๐ฅ •

The cover image looks good! haha

Collapse
 
klaudiagrz profile image
Klaudia Grzondziel •

Agree! ๐Ÿ’ฏ Looks awesome! ๐Ÿ˜„

Collapse
 
jim-wilson profile image
Jim Wilson •

Yep !!

Collapse
 
gramli profile image
Daniel Balcarek •

Thanks to both of you @technogamerz, @klaudiagrz ! I played around with it a lot. Did you notice the LOTR theme? ๐Ÿ˜„ Especially the hobbit and Smaug. ๐Ÿ˜„

Collapse
 
klaudiagrz profile image
Klaudia Grzondziel •

Ahahah, that was my guess! ๐Ÿ˜„ It gives LOTR or WoW vibes!

Thread Thread
 
gramli profile image
Daniel Balcarek •

You have an excellent eye! ๐Ÿ˜ฎ Iโ€™m pretty sure my first prompt included both LOTR and WoW (World of Warcraft). Iโ€™m a big fan of both btw. ๐Ÿ˜…

Thread Thread
 
klaudiagrz profile image
Klaudia Grzondziel •

I spent so much time on both that my eye couldn't have missed it ๐Ÿ˜‚ Damn, now I have the mood to play WoW again ๐Ÿฅน

Thread Thread
 
gramli profile image
Daniel Balcarek •

Oh no no no, donโ€™t tempt me! ๐Ÿคฃ Iโ€™m not going back to the dark side and playing all night again.๐Ÿคฃ๐Ÿ˜…

But honestly, the last time I played was during BfA, and then I tried Classic when it launched. Neither felt the same as when Vanilla or TBC originally came out. Classic came close, but perhaps that was mostly nostalgia. And BfA? It felt like a single-player MMO.

Thread Thread
 
klaudiagrz profile image
Klaudia Grzondziel •

Oh, I stopped playing right before Pandaria was released. Later on, I only saw some gameplay from Pandaria, but I haven't played myself.

Yeah, tempting to go back to it... ๐Ÿคฃ Maybe during retirement, when I'll have more time ๐Ÿ˜…

Thread Thread
 
gramli profile image
Daniel Balcarek •

That would be nice! ๐Ÿ˜„ But Iโ€™m not sure WoW will still be around by then. ๐Ÿ˜‚

Collapse
 
klaudiagrz profile image
Klaudia Grzondziel • • Edited

Hi Daniel, great article (and awesome cover image ๐Ÿ˜„)! One thing that stopped me:

reimplemented the entire client-side authentication flow directly against the existing corporate authentication service

I know I'm probably living in a dream world, but actually this is what should happen every time when testing a new feature. How did it look in your case? You did not have QAs test the feature? Or did nobody consider such a case? Now that I think about it, I probably wouldn't think of opening so many tabs ๐Ÿค” Interesting.

Collapse
 
gramli profile image
Daniel Balcarek •

Thanks! I hope I understood your question correctly. ๐Ÿ˜…

The feature was tested by our QAs, but this particular case was not discovered before the release. It required multiple tabs to refresh their tokens at just the right or wrong time, so it was an intermittent race condition rather than a consistently reproducible scenario.

One tab refreshed the token and invalidated the previous refresh token, while another tab was still trying to use it. The bigger problem was that the shared frontend library could not recover from the resulting 403 Forbidden response and left that tab completely stuck.

So yes, opening the application in multiple tabs was considered a normal use case, but nobody anticipated this exact token-refresh race condition during the original testing. Even after we identified it, the team maintaining the shared library was unable to reproduce it.. ๐Ÿ˜„

When I reimplemented the authentication flow(as part of the bug fix ๐Ÿ˜), it went through QA again. They tested the original scenario directly, but the fix was also exercised indirectly during other test cases where opening multiple tabs was part of the testing process.

Collapse
 
klaudiagrz profile image
Klaudia Grzondziel •

Ah, I see now. Thank you for the explanation. So tricky! ๐Ÿ›

Collapse
 
sylwia-lask profile image
Sylwia Laskowska •

Hahaha, that's a beautiful story! ๐Ÿคฃ Corporate "helpful" shared services at their finest.

We have something very similar in my company, too. The only difference is that ours isn't a collection of separate building blocks, but it's one huge framework. ๐Ÿ˜…

The people maintaining it seem to believe nobody will ever have to upgrade it, because every new version comes with breaking changes as if there were no tomorrow. They'll rename classes, methods... sometimes something goes from close() to closeDialog(), only to become close() again two versions later. Truly groundbreaking changes. ๐Ÿ˜‚

At this point, the more we work around it and build our own implementations where it makes sense, the healthier our project tends to be. ๐Ÿ˜„

Collapse
 
gramli profile image
Daniel Balcarek •

Thanks!

Thatโ€™s hilarious. ๐Ÿ˜‚ It looks like the lifecycle of these โ€œhelpfulโ€ shared services is the same in every corporation.๐Ÿ˜‚

Sometimes I feel like the maintainers develop these libraries mainly for their own test applications. At first, every team tries to use them to save time, but after enough struggles, many teams just reimplement the features themselves. Constant breaking changes combined with little willingness to fix bugs is just... corporate life. ๐Ÿ˜‚

Collapse
 
sylwia-lask profile image
Sylwia Laskowska •

Hahaha, and by the way, I see you've shown up with yet another great story... clearly you're after the skateboard I wanted to win! ๐Ÿคฃ

Thread Thread
 
gramli profile image
Daniel Balcarek •

Nah, I just wanted to share a funny story from my own experience. ๐Ÿ˜„ I donโ€™t think this is a winning one, there are plenty of much better submissions, including yours!

So let someone else break their leg on that skateboard. ๐Ÿคฃ

Collapse
 
webdeveloperhyper profile image
Web Developer Hyper •

Wow! You solved a problem that neither the frontend team nor the backend team could solve. I wouldn't expect anything less from you!ใ€€This post will definitely earn you even more fans around the world! ๐Ÿ˜

Collapse
 
gramli profile image
Daniel Balcarek •

Thanks, Iโ€™m glad you liked it!โค๏ธ

Youโ€™re overestimating me. ๐Ÿ˜… I think they were perfectly capable of fixing it, they just werenโ€™t willing to spend the time on what they considered an edge case.

Collapse
 
hiper2d profile image
Aliaksei Zelianouski •

I hate the ownership model so popular in large companies and enterprises - lots of specialized teams with their own managers and scopes. When something breaks in between, nobody is interested in fixing it. Not because they are lazy or something - it's just extra scope nobody planned. Cross-team coordination is painful, there is no single manager or lead who can clearly prioritize this.

Yeah, you found the best solution in this situation. Got rid of dependencies on teams you have no control over.

Collapse
 
gramli profile image
Daniel Balcarek •

Yes, thatโ€™s another side of the problem. When a team has multiple products to maintain, shared libraries often receive a lower priority, and managers may not want to allocate development capacity to them. Thanks for bringing up this perspective.

In this particular case, though, it wasnโ€™t that they completely ignored the issue they did spend time investigating it. I think the bigger problem was that they didnโ€™t want to prioritize a tricky bug that they considered an edge case.

Collapse
 
capestart profile image
CapeStart •

The fastest way to find out how many applications depend on your auth library is to introduce a bug in it. ๐Ÿ˜…

Collapse
 
gramli profile image
Daniel Balcarek •

Truer words have never been spoken. ๐Ÿคฃ๐Ÿคฃ

Collapse
 
henry_robt_ed01d31ae3d216 profile image
Henry Robt •

Great bug-smash story. The multi-tab token refresh race is a good example of how an intermittent issue can slip past normal testing, especially when multiple teams own different parts of the authentication flow. I also like the lesson about owning critical code when a shared dependency becomes a blockerโ€”sometimes simplifying the architecture is the best fix.

Collapse
 
gramli profile image
Daniel Balcarek •

Thanks! Glad you liked it. I agree, sometimes simplifying things ends up being the best fix.

Collapse
 
dropzilla_site_bee900de05 profile image
dp •

Great bug smash story! The multi-tab refresh token race condition is exactly the kind of issue that can waste days when ownership is split across different teams. I especially liked the decision to remove the shared library and take control of the authentication flow instead of waiting indefinitely for a fix.
Stories like this are really valuable for developers because they show that debugging is not only about finding the technical cause, but also about dealing with architecture and team boundaries. We share similar practical development experiences and tutorials on codecan.net, especially around web development and real-world coding problems, so this was a very relatable read.

Thanks for sharing the full investigation and the final solution!

Collapse
 
jacobfoster21 profile image
jacob foster •

Multi-tab authentication issues can be incredibly hard to trace, especially with shared services. A solid reminder to investigate beyond your own code.

Collapse
 
gramli profile image
Daniel Balcarek •

Yep, I think the debugging is one of the reasons why I still remember this bug even after all these years.