ఒకే వినియోగదారు తెరిచిన ఐదు ట్యాబ్‌లు ఒకే మిల్లీసెకనులో గడువు ముగిసిన JWTని రిఫ్రెష్ చేయడానికి ప్రయత్నించినప్పుడు, బ్యాకెండ్‌కు డూప్లికేట్ రిఫ్రెష్ రిక్వెస్ట్‌లు వెళ్లడం వల్ల 'టోకెన్ ట్రాప్' (token trap) ఒక లైవ్ సైట్‌పై ప్రభావం చూపింది, దీనివల్ల సెషన్ వెంటనే రద్దయింది. ప్రతి ట్యాబ్ వినియోగదారుని లాగ్ అవుట్ చేసింది, దీనివల్ల టోకెన్ పునరుద్ధరణకు (token renewal) కేవలం ఒకే ఒక ట్యాబ్ పరిష్కారం సరిపోదని నిరూపితమైంది.

టోకెన్ ట్రాప్ ఎందుకు ముఖ్యమైనది

ఆధునిక single-page apps తక్కువ కాలం ఉండే access tokens మరియు ఎక్కువ కాలం ఉండే refresh tokenను ఉపయోగిస్తాయి. Access token గడువు ముగిసినప్పుడు, క్లయింట్ ఒక refresh request పంపిస్తుంది, కొత్త token pairని అందుకుంటుంది మరియు అసలు కాల్‌ను మళ్ళీ ప్రయత్నిస్తుంది. చాలా మంది డెవలపర్లు ఈ ఫ్లోను in-memory flag (ఉదాహరణకు, isRefreshing = true) లేదా request queueతో కాపాడుతారు మరియు దీనిని ఒకే ఒక ట్యాబ్‌లో పరీక్షిస్తారు. కానీ వాస్తవ ప్రపంచంలో వినియోగదారులు సెట్టింగ్స్ పేజీ, అనలిటిక్స్ డ్యాష్‌బోర్డ్ మరియు కొన్ని డేటా వ్యూలతో కలిపి అనేక ట్యాబ్‌లను తెరిచి ఉంచుతారు. Access token గడువు ముగిసినప్పుడు, ప్రతి ట్యాబ్ స్వతంత్రంగా 401 errorని గుర్తిస్తుంది, ప్రతి ట్యాబ్ ఒక refresh requestను పంపిస్తుంది, మరియు బ్యాకెండ్—ముఖ్యంగా refresh-token rotationను అమలు చేస్తున్నప్పుడు—రెండవ రిక్వెస్ట్‌ను 'replay'గా పరిగణించి మొత్తం సెషన్‌ను రద్దు చేస్తుంది.

JavaScript ఐసోలేషన్ ఈ సమస్యకు కారణం

ప్రతి బ్రౌజర్ ట్యాబ్ దాని స్వంత JavaScript contextలో నడుస్తుంది. వేరియబుల్స్, టైమర్లు మరియు in-memory flags ఒకే originని పంచుకున్నప్పటికీ ఇతర ట్యాబ్‌లకు కనిపించవు. “a refresh is already in progress” అని చెప్పే ఒక flag, దానిని సెట్ చేసిన ట్యాబ్‌లో మాత్రమే ఉంటుంది. టోకెన్ ఎక్కడో రిఫ్రెష్ అవుతోందని తెలుసుకోవడానికి ఇతర ట్యాబ్‌లకు మార్గం లేదు, కాబట్టి అవి కూడా తమ స్వంత నెట్‌వర్క్ కాల్‌లను ప్రారంభిస్తాయి. ఈ సమస్య interceptorలో ఉన్న బగ్ కాదు; ఇది client-side state isolation యొక్క ప్రాథమిక పరిమితి.

Web Locks API పరిష్కారం చూపుతుంది

ఒక ట్యాబ్ లాక్ (lock) కలిగి ఉన్నప్పుడు, అదే లాక్ కోసం అడిగే ఇతర ట్యాబ్‌లు అది విడుదలయ్యే వరకు వేచి ఉండాలి.

టోకెన్ రిఫ్రెష్ కోసం ఇది ఎలా పనిచేస్తుంది

  1. 401ని గుర్తించడం – అనధికారిక (unauthorized) స్పందనను అందుకునే ఏ ట్యాబ్ అయినా navigator.locks.request('auth_token_refresh_lock', async lock => { … })ని పిలుస్తుంది.
  2. లాక్‌ను పొందడం – వేరే ఏ ట్యాబ్ లాక్‌ను కలిగి లేకపోతే, ప్రస్తుత ట్యాబ్ ముందుకు వెళ్తుంది; లేకపోతే లాక్ ఖాళీ అయ్యే వరకు అది ఆగుతుంది.
  3. ఒక్కసారి మాత్రమే రిఫ్రెష్ చేయడం – లాక్ కలిగి ఉన్న ట్యాబ్ refresh requestను పంపిస్తుంది, కొత్త access token మరియు timestampని localStorageలో నిక్షిప్తం చేస్తుంది, ఆపై callback పూర్తయినప్పుడు ఆటోమేటిక్‌గా లాక్‌ను విడుదల చేస్తుంది.
  4. డూప్లికేట్ పనిని నివారించడం – వేచి ఉన్న ట్యాబ్ చివరకు లాక్‌ను పొందినప్పుడు, అది localStorage నుండి timestampని చదువుతుంది. ఒకవేళ టోకెన్ నిర్ణీత సమయంలో (ఉదాహరణకు, చివరి కొన్ని సెకన్లలో) రిఫ్రెష్ చేయబడితే, ఆ ట్యాబ్ నెట్‌వర్క్ కాల్‌ను వదిలేసి, localStorage నుండి దాని in-memory టోకెన్‌ను అప్‌డేట్ చేసుకుంటుంది.
  5. క్రాష్‌లను హ్యాండిల్ చేయడం – లాక్ కలిగి ఉన్నప్పుడు ఒక ట్యాబ్ క్రాష్ అయినా లేదా మూసివేయబడినా, బ్రౌజర్ ఆ లాక్‌ను విడుదల చేస్తుంది, తద్వారా మరొక ట్యాబ్ రిఫ్రెష్‌ను మళ్ళీ ప్రయత్నించవచ్చు.

ప్రయోజనాలు ఒక చూపులో

  • అనవసరమైన నెట్‌వర్క్ కాల్స్ ఉండవు – మొదటి ట్యాబ్ మాత్రమే బ్యాకెండ్‌తో మాట్లాడుతుంది.
  • సెషన్ రద్దవ్వదు – Refresh-token rotation ఒకేసారి ఉపయోగించబడటం వల్ల సెషన్ కొనసాగుతుంది.
  • సులభమైన రికవరీ – ఒక ట్యాబ్ కనిపించకుండా పోయినా, బ్రౌజర్ ద్వారా నిర్వహించబడే లాక్ విడుదల ప్రక్రియ డెడ్‌లాక్‌లను (deadlocks) నివారిస్తుంది.

ఇంప్లిమెంటేషన్ చెక్‌లిస్ట్

  • మీ Axios (లేదా fetch) interceptorలో రిఫ్రెష్ లాజిక్‌ను లాక్ రిక్వెస్ట్‌తో కలిపి ఉంచండి.
  • రిఫ్రెష్ చేసిన టోకెన్ మరియు మిల్లీసెకండ్ timestampని localStorageలో (లేదా సెషన్ డేటా కావాలనుకుంటే sessionStorageలో) నిక్షిప్తం చేయండి.
  • లాక్ లభించినప్పుడు, నిక్షిప్తం చేసిన timestampని Date.now()తో పోల్చండి. తేడా మీ థ్రెషోల్డ్ (threshold) కంటే తక్కువగా ఉంటే, బ్యాకెండ్‌ను పిలవడానికి బదులుగా స్టోరేజ్ నుండి టోకెన్‌ను చదవండి.
  • అసలు API కాల్‌ను మళ్ళీ ప్రయత్నించే ముందు, ఇంటర్సెప్టర్ స్టోరేజ్ నుండి పొందిన టోకెన్‌తో రిక్వెస్ట్ హెడర్‌లను అప్‌డేట్ చేసేలా చూసుకోండి.
  • నెట్‌వర్క్ లాటెన్సీని (network latency) అనుకరిస్తూ, కేవలం ఒకే ఒక రిఫ్రెష్ రిక్వెస్ట్ సర్వర్‌కు చేరుతుందో లేదో తనిఖీ చేయడానికి బహుళ ట్యాబ్‌లతో ఈ ఫ్లోను పరీక్షించండి.

ఏవైనా సమస్యలు రావచ్చు

తదుపరి గమనించవలసినవి

ముగింపు (Takeaway)

ప్రతి బ్రౌజర్ ట్యాబ్‌ను ఒక చిన్న డిస్ట్రిబ్యూటెడ్ సిస్టమ్‌లోని (distributed system) నోడ్‌గా పరిగణించండి. JWT రిఫ్రెష్‌లను సీరియలైజ్ చేయడానికి Web Locks APIని ఉపయోగించడం ద్వారా, మీరు డూప్లికేట్ కాల్‌లను నివారించవచ్చు, refresh-token rotationను రక్షించవచ్చు మరియు వినియోగదారులు తెరిచిన అన్ని ట్యాబ్‌లలో లాగిన్ అయి ఉండేలా చూడవచ్చు.