Web Locks API ఐదు ఓపెన్ ట్యాబ్‌లు ఒకేసారి auth సర్వర్‌కు refresh-token కాల్స్ పంపి పదేపదే ఇబ్బంది పెట్టకుండా ఆపగలదు, తద్వారా వినియోగదారులు అకస్మాత్తుగా లాగ్ అవుట్ అవ్వకుండా కాపాడుతుంది. ట్యాబ్‌ల మధ్య రిఫ్రెష్‌లను సమన్వయం చేయడం ద్వారా, Refresh Token Rotation ఉపయోగిస్తున్నప్పుడు సాధారణంగా సెషన్‌ను ముగించే (session-kill) భారీ రిక్వెస్ట్‌ల బదులు, ఒకే ఒక రిక్వెస్ట్ సరిపోతుంది.

మల్టీ-ట్యాబ్ సెషన్‌లో దాగి ఉన్న ఓవర్‌లోడ్

సాధారణంగా ఒక single-page app, 401 రెస్పాన్స్‌ను గమనించడానికి ఒక Axios interceptorను ఉపయోగిస్తుంది, ఇది isRefreshing అనే Boolean ఫ్లాగ్‌ను మారుస్తుంది మరియు కొత్త JWT వచ్చే వరకు బయటకు వెళ్లే రిక్వెస్ట్‌లను క్యూ (queue) చేస్తుంది. ఒకే ట్యాబ్‌లో పరీక్షించినప్పుడు, ఈ ప్రక్రియ అద్భుతంగా పనిచేస్తుంది.

అదే యాప్‌ను ఐదు ట్యాబ్‌లలో ఓపెన్ చేసి, access token గడువు ముగిసేలా చేస్తే, ఆ ఐదు ట్యాబ్‌లు కూడా ఒకే మిల్లీసెకనులో 401 రెస్పాన్స్‌ను గమనిస్తాయి. ప్రతి ట్యాబ్ కూడా రిఫ్రెష్ చేయాలని అనుకుంటుంది, కాబట్టి ఐదు ఒకే రకమైన refresh-token రిక్వెస్ట్‌లు auth సర్వర్‌కు చేరుతాయి. Refresh Token Rotation—అంటే కొత్త రిఫ్రెష్ టోకెన్ జారీ చేయగానే పాత రిఫ్రెష్ టోకెన్‌ను చెల్లకుండా చేసే భద్రతా చర్య—ఉన్నప్పుడు, సర్వర్ రెండవ రిక్వెస్ట్‌ను 'replay attack'గా పరిగణిస్తుంది, సెషన్‌ను ప్రమాదకరమైనదిగా గుర్తించి, దానిని రద్దు చేస్తుంది. ఫలితంగా వినియోగదారు అన్ని ట్యాబ్‌ల నుండి వెంటనే లాగ్ అవుట్ అయిపోతారు.

దీనికి ప్రధాన కారణం JavaScript యొక్క isolation model. isRefreshing వంటి వేరియబుల్ దాన్ని సెట్ చేసిన ట్యాబ్‌లో మాత్రమే ఉంటుంది; రిఫ్రెష్ ప్రక్రియ ఇప్పటికే జరుగుతోందని ఇతర ట్యాబ్‌లకు తెలియదు. ఇది ఒక క్లాసిక్ concurrency సమస్య, కానీ ఇక్కడ "processes" అంటే threads కాకుండా బ్రౌజర్ ట్యాబ్‌లు.

క్రాస్-ట్యాబ్ లాక్ (cross-tab lock) ఎందుకు సరైన సాధనం?

ట్యాబ్‌లు ఒక ఉమ్మడి వనరు (shared resource)—ఈ సందర్భంలో, కొత్త JWT—గురించి ఒకదానితో ఒకటి మాట్లాడుకోవడానికి మనకు ఒక మార్గం కావాలి. navigator.locks రూపంలో అందుబాటులో ఉన్న Web Locks API సరిగ్గా అదే చేస్తుంది. ఇది ఒకే origin కి చెందిన అన్ని సందర్భాలలో (contexts) బ్రౌజర్ అమలు చేసే ఒక 'named lock'ను స్క్రిప్ట్‌లు కోరడానికి అనుమతిస్తుంది. ఒకవేళ లాక్ ఇప్పటికే ఎవరికైనా ఉంటే, ఆ లాక్ విడుదల చేసే వరకు లేదా బ్రౌజర్ దానిని రద్దు చేసే వరకు (ఉదాహరణకు, ట్యాబ్ క్రాష్ అయినప్పుడు) ఇతర రిక్వెస్ట్‌లు క్యూలో ఉంటాయి. దీనికి ఎటువంటి బాహ్య సర్వర్ లేదా polling అవసరం లేదు, కేవలం నేటివ్ బ్రౌజర్ సమన్వయం మాత్రమే సరిపోతుంది.

లాక్-ఆధారిత రిఫ్రెష్ ఫ్లోను అమలు చేయడం

  1. 401ని గుర్తించడం – Axios interceptor మునుపటిలాగే అనధికారిక (unauthorized) రెస్పాన్స్‌ను గుర్తిస్తుంది.
  2. Exclusive lock కోసం అడగడం – ట్యాబ్ navigator.locks.request('auth_token_refresh_lock', async lock => { … })ను పిలుస్తుంది. ఒక సమయంలో ఒక ట్యాబ్ మాత్రమే callback లోకి ప్రవేశించగలదు.
  3. నెట్‌వర్క్‌కు వెళ్లే ముందు మళ్ళీ తనిఖీ చేయడం – లాక్ లోపల, localStorage నుండి టైమ్‌స్టాంప్‌ను (లేదా టోకెన్‌ను) చదవండి. ఆ టైమ్‌స్టాంప్ కొన్ని సెకన్ల కంటే తక్కువ సమయం క్రితం నాటిది అయితే, మరొక ట్యాబ్ ఇప్పటికే టోకెన్‌ను రిఫ్రెష్ చేసిందని అర్థం; ప్రస్తుత ట్యాబ్ నెట్‌వర్క్ కాల్ చేయకుండా నేరుగా స్టోరేజ్ నుండి కొత్త JWTని చదువుతుంది.
  4. అవసరమైతే రిఫ్రెష్ చేయడం – స్టోర్ చేసిన టైమ్‌స్టాంప్ పాతదైతే, రిఫ్రెష్ రిక్వెస్ట్‌ను పంపి, కొత్త టోకెన్ మరియు ప్రస్తుత సమయాన్ని localStorageలో నిక్షిప్తం చేసి, ఆపై callback నుండి తిరిగి రావడం ద్వారా లాక్‌ను విడుదల చేస్తుంది.
  5. క్యూలో ఉన్న రిక్వెస్ట్‌లను కొనసాగించడం – వేచి ఉన్న మిగిలిన అన్ని ట్యాబ్‌లు ఒకదాని తర్వాత ఒకటి లాక్‌ను పొందుతాయి, తాజా టైమ్‌స్టాంప్‌ను చూస్తాయి మరియు మళ్ళీ రిక్వెస్ట్ చేయకుండా ప్రక్రియను పూర్తి చేస్తాయి.
async function refreshIfNeeded() {
  await navigator.locks.request('auth_token_refresh_lock', async lock => {
    const lastRefresh = Number(localStorage.getItem('token_refreshed_at') || 0);
    const now = Date.now();
    if (now - lastRefresh < 5_000) return; // another tab already refreshed

    const newToken = await callRefreshEndpoint(); // actual network call
    localStorage.setItem('jwt', newToken);
    localStorage.setItem('token_refreshed_at', now.toString());
  });
}

ఎన్ని ట్యాబ్‌లు ఓపెన్ చేసి ఉన్నా, కేవలం ఒకే ఒక రిఫ్రెష్ రిక్వెస్ట్ సర్వర్‌కు చేరుతుందని ఈ పద్ధతి హామీ ఇస్తుంది.

మీరు కొలవగల ప్రయోజనాలు

  • నెట్‌వర్క్ సామర్థ్యం (Network efficiency) – ఐదు రిక్వెస్ట్‌లకు బదులుగా ఒకే రిక్వెస్ట్ ఉండటం వల్ల బ్యాండ్‌విడ్త్ మరియు సర్వర్ లోడ్ గణనీయంగా తగ్గుతాయి.
  • సెషన్ భద్రత (Session safety) – Refresh Token Rotationతో, సర్వర్ పాత రిఫ్రెష్ టోకెన్‌ను ఒకే ఒక్కసారి చూస్తుంది, కాబట్టి సెషన్‌ను ప్రమాదకరమైనదిగా గుర్తించదు.
  • స్థితస్థాపకత (Resilience) – లాక్ కలిగి ఉన్న ట్యాబ్ క్రాష్ అయితే, బ్రౌజర్ ఆటోమేటిక్‌గా లాక్‌ను విడుదల చేస్తుంది, దీనివల్ల అన్ని ట్యాబ్‌లు నిలిచిపోయే (deadlock) పరిస్థితి రాదు.
  • స్కేలబిలిటీ (Scalability) – వినియోగదారులు డజన్ల కొద్దీ ట్యాబ్‌లను ఓపెన్ చేసినా, లాగ్ అవుట్ అయ్యే ప్రమాదం ఉండదు, ఎందుకంటే సమన్వయం అంతా బ్రౌజర్ లోపలే జరుగుతుంది.

మరో కోణం: బ్రౌజర్ సపోర్ట్ మరియు ఫాల్‌బ్యాక్స్ (fallbacks)

Web Locks API అనేది సాపేక్షంగా కొత్త ఫీచర్. ఆధునిక Chromium-ఆధారిత బ్రౌజర్‌లు మరియు ఇటీవలి Firefox వెర్షన్‌లు దీనిని అమలు చేస్తున్నాయి, కానీ పాత బ్రౌజర్‌లు మరియు Safariలో దీనికి నేటివ్ సపోర్ట్ లేదు. ఈ API అందుబాటులో లేని చోట, డెవలపర్లు localStorage ద్వారా కస్టమ్ ఈవెంట్‌ను బ్రాడ్‌కాస్ట్ చేయడం లేదా shared worker ఉపయోగించడం వంటి తక్కువ నమ్మదగిన పద్ధతులను (fallbacks) ఉపయోగించాల్సి ఉంటుంది. ఈ పద్ధతుల్లో navigator.locks అందించే ఆటోమేటిక్ డెడ్-లాక్ ప్రొటెక్షన్ ఉండదు, కాబట్టి వీటిని జాగ్రత్తగా ఉపయోగించాలి.

తదుపరి ఏమి చూడాలి

  • ప్రామాణీకరణ పురోగతి – API యొక్క అడాప్షన్ కర్వ్‌పై (adoption curve) నిఘా ఉంచండి; విస్తృత మద్దతు లభిస్తే, ఏదైనా క్రాస్-ట్యాబ్ కోఆర్డినేషన్ కోసం లాక్-ఆధారిత విధానం డిఫాల్ట్‌గా మారుతుంది.
  • లైబ్రరీ రాపర్స్ – కొన్ని ఓపెన్-సోర్స్ యుటిలిటీలు ఇప్పటికే లాక్ రిక్వెస్ట్ ప్యాటర్న్‌ను అబ్‌స్ట్రాక్ట్ చేస్తున్నాయి, దీనివల్ల ఇప్పటికే ఉన్న Axios interceptors లలో వీటిని అనుసంధానించడం సులభతరం అవుతుంది.
  • సెక్యూరిటీ ఆడిట్లు – లాక్ అనేది కన్కరెన్సీ సమస్యను పరిష్కరించినప్పటికీ, రిఫ్రెష్ ఎండ్‌పాయింట్ తప్పనిసరిగా సరైన టోకెన్ రొటేషన్ మరియు రేట్ లిమిటింగ్‌ను అమలు చేయాలి; ఎందుకంటే లాక్ బైపాస్ చేయబడితే, ఒకే ఒక మాలిషియస్ ట్యాబ్ సర్వర్‌ను రిక్వెస్ట్‌లతో ముంచెత్తే అవకాశం ఉంది.

దీని సారాంశం సరళమైనది: తెరిచి ఉన్న ట్యాబ్‌ల సమూహాన్ని ఒక డిస్ట్రిబ్యూటెడ్ సిస్టమ్‌గా పరిగణించి, వాటికి ఒక నేటివ్ సింక్రొనైజేషన్ ప్రిమిటివ్‌ను అందించాలి. Web Locks APIని టోకెన్-రిఫ్రెష్ ఫ్లోలోకి అనుసంధానించడం ద్వారా, డెవలపర్లు “browser tab token trap” సమస్యను నివారించవచ్చు మరియు వినియోగదారులు ఎన్ని ట్యాబ్‌లను ఉపయోగిస్తున్నప్పటికీ, వారిని లాగిన్ స్థితిలోనే ఉంచవచ్చు.