જ્યારે એક જ યુઝર દ્વારા ખોલેલા પાંચ ટેબ્સ એક જ મિલીસેકન્ડમાં એક્સપાયર થયેલ JWT ને રિફ્રેશ કરવાનો પ્રયાસ કરે છે, ત્યારે 'ટોકન ટ્રેપ' એક લાઇવ સાઇટ પર જોવા મળ્યું હતું. આના કારણે બેકએન્ડમાં ડુપ્લીકેટ રિફ્રેશ રિક્વેસ્ટનો પૂર આવ્યો અને તરત જ સેશન અમાન્ય બની ગયું. દરેક ટેબમાંથી યુઝર લોગ આઉટ થઈ ગયો, જે સાબિત કરે છે કે ટોકન રિન્યુઅલ માટે સિંગલ-ટેબ સોલ્યુશન હવે પૂરતું નથી.
ટોકન ટ્રેપ શા માટે મહત્વનું છે
આધુનિક સિંગલ-પેજ એપ્સ ટૂંકા સમય માટેના એક્સેસ ટોકન્સ અને લાંબા સમય માટેના રિફ્રેશ ટોકનનો ઉપયોગ કરે છે. જ્યારે એક્સેસ ટોકન એક્સપાયર થાય છે, ત્યારે ક્લાયન્ટ એક રિફ્રેશ રિક્વેસ્ટ મોકલે છે, નવું ટોકન પેર મેળવે છે, અને મૂળ કોલ ફરીથી કરવાનો પ્રયાસ કરે છે. મોટાભાગના ડેવલપર્સ આ ફ્લોને ઇન-મેમરી ફ્લેગ (દા.ત., isRefreshing = true) અથવા રિક્વેસ્ટ ક્યુ દ્વારા સુરક્ષિત કરે છે, અને તેને સિંગલ ટેબમાં ટેસ્ટ કરે છે. વાસ્તવિક દુનિયામાં યુઝર્સ ઘણા ટેબ્સ ખુલ્લા રાખે છે: જેમ કે સેટિંગ્સ પેજ, એનાલિટિક્સ ડેશબોર્ડ અને કેટલાક ડેટા વ્યુઝ. જ્યારે એક્સેસ ટોકન એક્સપાયર થાય છે, ત્યારે દરેક ટેબ સ્વતંત્ર રીતે 401 એરરને ડિટેક્ટ કરે છે, દરેક રિફ્રેશ રિક્વેસ્ટ મોકલે છે, અને બેકએન્ડ—ખાસ કરીને જ્યારે તે રિફ્રેશ-ટોકન રોટેશન લાગુ કરે છે—ત્યારે તે બીજી રિક્વેસ્ટને 'રીપ્લે' તરીકે ગણે છે અને આખું સેશન રદ કરી દે છે.
JavaScript આઇસોલેશન સમસ્યા ઊભી કરે છે
દરેક બ્રાઉઝર ટેબ પોતાનો અલગ JavaScript કોન્ટેક્સ્ટ ચલાવે છે. વેરીએબલ્સ, ટાઈમર્સ અને ઇન-મેમરી ફ્લેગ્સ અન્ય ટેબ્સ માટે અદ્રશ્ય હોય છે, ભલે તેઓ સમાન ઓરિજિન શેર કરતા હોય. "રિફ્રેશ પહેલેથી જ ચાલુ છે" એવું કહેતો ફ્લેગ ફક્ત તે ટેબની અંદર જ રહે છે જેણે તેને સેટ કર્યો છે. અન્ય ટેબ્સ પાસે એ જાણવાનો કોઈ રસ્તો નથી કે ટોકન બીજે ક્યાંક રિફ્રેશ થઈ રહ્યું છે, તેથી તેઓ બધા પોતાની નેટવર્ક કોલ શરૂ કરે છે. આ સમસ્યા ઇન્ટરસેપ્ટરમાં રહેલી કોઈ બગ નથી; તે ક્લાયન્ટ-સાઇડ સ્ટેટ આઇસોલેશનની મૂળભૂત મર્યાદા છે.
Web Locks API બચાવ માટે તૈયાર છે
જ્યારે કોઈ ટેબ લોક (lock) પકડી રાખે છે, ત્યારે તે જ લોક માટે પૂછતી અન્ય કોઈપણ ટેબ જ્યાં સુધી તે લોક મુક્ત ન થાય ત્યાં સુધીએ રાહ જોવી પડે છે.
ટોકન રિફ્રેશ માટે તે કેવી રીતે કામ કરે છે
- 401 ડિટેક્ટ કરો – જે પણ ટેબ અનોથોરાઇઝ્ડ રિસ્પોન્સ મેળવે છે તે
navigator.locks.request('auth_token_refresh_lock', async lock => { … })કોલ કરે છે. - લોક મેળવો – જો અન્ય કોઈ ટેબ પાસે લોક ન હોય, તો વર્તમાન ટેબ આગળ વધે છે; અન્યથા લોક મુક્ત ન થાય ત્યાં સુધી તે અટકી જાય છે.
- એક જ વાર રિફ્રેશ કરો – લોક ધારક રિફ્રેશ રિક્વેસ્ટ મોકલે છે, નવો એક્સેસ ટોકન અને ટાઇમસ્ટેમ્પ
localStorageમાં સ્ટોર કરે છે, અને પછી કોલબેક પૂરું થતા લોક આપમેળે રિલીઝ કરે છે. - ડુપ્લીકેટ કામ ટાળો – જ્યારે રાહ જોતું ટેબ અંતે લોક મેળવે છે, ત્યારે તે
localStorageમાંથી ટાઇમસ્ટેમ્પ વાંચે છે. જો ટોકન નિર્ધારિત સમયગાળામાં (દા.ત., છેલ્લા થોડા સેકન્ડોમાં) રિફ્રેશ થયું હોય, તો ટેબ નેટવર્ક કોલ સ્કીપ કરે છે અનેlocalStorageમાંથી તેનું ઇન-મેમરી ટોકન અપડેટ કરે છે. - ક્રેશ હેન્ડલ કરો – જો લોક પકડી રાખી હોય તે દરમિયાન ટેબ ક્રેશ થાય અથવા બંધ થઈ જાય, તો બ્રાઉઝર લોક રિલીઝ કરે છે, જેનાથી અન્ય ટેબ રિફ્રેશ ફરીથી કરવાનો પ્રયાસ કરી શકે છે.
એક નજરમાં ફાયદા
- ઝીરો રિડન્ડન્ટ નેટવર્ક કોલ્સ – ફક્ત પ્રથમ ટેબ જ બેકએન્ડ સાથે વાત કરે છે.
- સેશન ડિસ્ટ્રક્શન નહીં – રિફ્રેશ-ટોકન રોટેશનમાં માત્ર એક જ ઉપયોગ દેખાય છે, જેનાથી સેશન જીવંત રહે છે.
- ગ્રેસફુલ રિકવરી – બ્રાઉઝર-મેનેજ્ડ લોક રિલીઝ ટેબ ગાયબ થઈ જાય તો ડેડલોક અટકાવે છે.
ઇમ્પ્લીમેન્ટેશન ચેકલિસ્ટ
- તમારા Axios (અથવા fetch) ઇન્ટરસેપ્ટરમાં લોક રિક્વેસ્ટ સાથે રિફ્રેશ લોજિકને રેપ (wrap) કરો.
- રિફ્રેશ થયેલ ટોકન અને મિલીસેકન્ડ ટાઇમસ્ટેમ્પ
localStorageમાં સ્ટોર કરો (અથવા જો તમે પર્સ-સેશન ડેટા પસંદ કરતા હોવ તોsessionStorageમાં). - જ્યારે લોક આપવામાં આવે, ત્યારે સ્ટોર કરેલા ટાઇમસ્ટેમ્પની
Date.now()સાથે સરખામણી કરો. જો તફાવત તમારા થ્રેશોલ્ડ (threshold) કરતા ઓછો હોય, તો બેકએન્ડને કોલ કરવાને બદલે સ્ટોરેજમાંથી ટોકન વાંચો. - ખાતરી કરો કે ઇન્ટરસેપ્ટર મૂળ API કોલ ફરીથી કરવાનો પ્રયાસ કરતા પહેલા સ્ટોરેજમાંથી મેળવેલા ટોકન સાથે રિક્વેસ્ટ હેડર્સ અપડેટ કરે છે.
- નેટવર્ક લેટન્સી (latency) સિમ્યુલેટ કરીને અને મલ્ટિપલ ટેબ્સ સાથે ફ્લો ટેસ્ટ કરો જેથી ખાતરી કરી શકાય કે માત્ર એક જ રિફ્રેશ રિક્વેસ્ટ સર્વર સુધી પહોંચે છે.
શું ખોટું થઈ શકે છે
આગળ શું ધ્યાન રાખવું
મુખ્ય વાત (Takeaway)
દરેક બ્રાઉઝર ટેબને એક નાના ડિસ્ટ્રિબ્યુટેડ સિસ્ટમમાં નોડ તરીકે ગણો. JWT રિફ્રેશને સીરીયલાઈઝ કરવા માટે Web Locks API નો ઉપયોગ કરીને, તમે ડુપ્લીકેટ કોલ્સને દૂર કરો છો, રિફ્રેશ-ટોકન રોટેશનનું રક્ષણ કરો છો, અને યુઝર્સને તેમના તમામ ખુલ્લા ટેબ્સમાં લોગ ઇન રાખશો.
