[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-en-\u002Fblog\u002Fauthentication-strategies-\u002Fen\u002Fblog\u002Fauthentication-strategies":3,"blog-post-surround-en-\u002Fblog\u002Fauthentication-strategies-\u002Fen\u002Fblog\u002Fauthentication-strategies":4668,"related-posts-en-\u002Fblog\u002Fauthentication-strategies-\u002Fen\u002Fblog\u002Fauthentication-strategies":4677},{"id":4,"title":5,"authors":6,"badge":13,"body":15,"categories":4622,"date":4624,"description":4625,"extension":4626,"image":4627,"meta":4629,"navigation":3009,"path":4659,"readingTime":341,"seo":4660,"stem":4661,"tags":4662,"__hash__":4667},"posts_en\u002Fblog\u002F12.authentication-strategies.md","Authentication Strategies: Secure, Fast User Management",[7],{"name":8,"to":9,"avatar":10,"bio":12},"Marcel Posdijk","https:\u002F\u002Fx.com\u002Fmarcelposdijk",{"src":11},"\u002Fimages\u002Fteam\u002Fmarcel.jpg","Founder and lead developer at Ludulicious B.V. with over 25 years of experience in web development and software architecture.",{"label":14},"Security",{"type":16,"value":17,"toc":4596},"minimark",[18,23,27,33,67,72,104,115,119,124,127,132,163,167,171,174,864,869,893,899,903,906,2089,2093,2119,2124,2128,2131,2932,2936,2962,2967,2971,2975,2978,3074,3085,3089,3092,3726,3736,3740,3744,3754,3759,3789,3794,4303,4306,4310,4335,4339,4363,4367,4393,4397,4400,4471,4475,4478,4514,4518,4521,4524,4527,4549,4554,4561,4583,4586,4592],[19,20,22],"h2",{"id":21},"the-problem-authentication-performance-and-security-trade-offs","The Problem: Authentication Performance and Security Trade-offs",[24,25,26],"p",{},"In 2023, we were building customer portals where authentication was either secure but slow, or fast but vulnerable. Clients demanded both security and performance, but traditional approaches forced us to choose between them.",[24,28,29],{},[30,31,32],"strong",{},"The Challenge:",[34,35,36,43,49,55,61],"ul",{},[37,38,39,42],"li",{},[30,40,41],{},"Security vs Performance",": Secure auth was slow, fast auth was insecure",[37,44,45,48],{},[30,46,47],{},"Multiple Providers",": Clients wanted Google, Microsoft, GitHub, and email\u002Fpassword",[37,50,51,54],{},[30,52,53],{},"Session Management",": Complex session handling across multiple devices",[37,56,57,60],{},[30,58,59],{},"User Experience",": Long login times frustrated users",[37,62,63,66],{},[30,64,65],{},"Compliance",": GDPR, SOC2, and industry-specific requirements",[24,68,69],{},[30,70,71],{},"The Numbers:",[34,73,74,80,86,92,98],{},[37,75,76,79],{},[30,77,78],{},"Login Time",": 3-5 seconds (too slow for modern users)",[37,81,82,85],{},[30,83,84],{},"Security Vulnerabilities",": 15% of applications had auth flaws",[37,87,88,91],{},[30,89,90],{},"User Drop-off",": 40% abandoned registration due to complexity",[37,93,94,97],{},[30,95,96],{},"Support Tickets",": 60% related to authentication issues",[37,99,100,103],{},[30,101,102],{},"Development Time",": 40% of project time spent on auth",[24,105,106],{},[107,108],"img",{"alt":109,"className":110,"height":112,"src":113,"width":114},"Authentication challenges",[111],"rounded-lg",600,"https:\u002F\u002Fpicsum.photos\u002Fid\u002F16\u002F1000\u002F600",1000,[19,116,118],{"id":117},"the-solution-modern-authentication-architecture","The Solution: Modern Authentication Architecture",[120,121,123],"h3",{"id":122},"our-approach-security-first-performance","Our Approach: Security-First Performance",[24,125,126],{},"We developed a comprehensive authentication strategy that prioritizes security while maintaining optimal performance:",[24,128,129],{},[30,130,131],{},"Key Innovations:",[34,133,134,140,146,152,157],{},[37,135,136,139],{},[30,137,138],{},"Multi-Provider Support",": Seamless integration with major providers",[37,141,142,145],{},[30,143,144],{},"Performance Optimization",": Sub-100ms authentication operations",[37,147,148,151],{},[30,149,150],{},"Security Best Practices",": Industry-standard security measures",[37,153,154,156],{},[30,155,59],{},": Frictionless login and registration flows",[37,158,159,162],{},[30,160,161],{},"Compliance Ready",": Built-in GDPR and SOC2 compliance",[19,164,166],{"id":165},"authentication-architecture","Authentication Architecture",[120,168,170],{"id":169},"_1-multi-provider-authentication-strategy","1. Multi-Provider Authentication Strategy",[24,172,173],{},"We implemented a unified authentication system supporting multiple providers:",[175,176,181],"pre",{"className":177,"code":178,"language":179,"meta":180,"style":180},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Unified authentication configuration\nexport const authConfig = {\n  providers: {\n    \u002F\u002F OAuth2 providers\n    google: {\n      clientId: process.env.GOOGLE_CLIENT_ID,\n      clientSecret: process.env.GOOGLE_CLIENT_SECRET,\n      scopes: ['email', 'profile']\n    },\n    microsoft: {\n      clientId: process.env.MICROSOFT_CLIENT_ID,\n      clientSecret: process.env.MICROSOFT_CLIENT_SECRET,\n      tenant: process.env.MICROSOFT_TENANT_ID\n    },\n    github: {\n      clientId: process.env.GITHUB_CLIENT_ID,\n      clientSecret: process.env.GITHUB_CLIENT_SECRET,\n      scopes: ['user:email']\n    },\n    \n    \u002F\u002F Email\u002Fpassword provider\n    email: {\n      enabled: true,\n      requireEmailVerification: true,\n      passwordPolicy: {\n        minLength: 8,\n        requireUppercase: true,\n        requireNumbers: true,\n        requireSpecialChars: true\n      }\n    }\n  },\n  \n  \u002F\u002F Security features\n  security: {\n    twoFactor: {\n      enabled: true,\n      methods: ['totp', 'sms', 'email']\n    },\n    sessionManagement: {\n      maxAge: 30 * 24 * 60 * 60 * 1000, \u002F\u002F 30 days\n      refreshThreshold: 7 * 24 * 60 * 60 * 1000, \u002F\u002F 7 days\n      maxConcurrentSessions: 5\n    },\n    rateLimiting: {\n      loginAttempts: 5,\n      windowMs: 15 * 60 * 1000, \u002F\u002F 15 minutes\n      blockDuration: 30 * 60 * 1000 \u002F\u002F 30 minutes\n    }\n  }\n};\n","typescript","",[182,183,184,193,215,227,233,243,268,289,323,329,339,359,379,398,403,413,433,453,471,476,482,488,498,512,524,534,548,560,572,583,589,595,601,607,613,623,633,644,680,685,695,731,763,774,779,789,802,826,847,852,858],"code",{"__ignoreMap":180},[185,186,189],"span",{"class":187,"line":188},"line",1,[185,190,192],{"class":191},"sHwdD","\u002F\u002F Unified authentication configuration\n",[185,194,196,200,204,208,212],{"class":187,"line":195},2,[185,197,199],{"class":198},"s7zQu","export",[185,201,203],{"class":202},"spNyl"," const",[185,205,207],{"class":206},"sTEyZ"," authConfig ",[185,209,211],{"class":210},"sMK4o","=",[185,213,214],{"class":210}," {\n",[185,216,218,222,225],{"class":187,"line":217},3,[185,219,221],{"class":220},"swJcz","  providers",[185,223,224],{"class":210},":",[185,226,214],{"class":210},[185,228,230],{"class":187,"line":229},4,[185,231,232],{"class":191},"    \u002F\u002F OAuth2 providers\n",[185,234,236,239,241],{"class":187,"line":235},5,[185,237,238],{"class":220},"    google",[185,240,224],{"class":210},[185,242,214],{"class":210},[185,244,246,249,251,254,257,260,262,265],{"class":187,"line":245},6,[185,247,248],{"class":220},"      clientId",[185,250,224],{"class":210},[185,252,253],{"class":206}," process",[185,255,256],{"class":210},".",[185,258,259],{"class":206},"env",[185,261,256],{"class":210},[185,263,264],{"class":206},"GOOGLE_CLIENT_ID",[185,266,267],{"class":210},",\n",[185,269,271,274,276,278,280,282,284,287],{"class":187,"line":270},7,[185,272,273],{"class":220},"      clientSecret",[185,275,224],{"class":210},[185,277,253],{"class":206},[185,279,256],{"class":210},[185,281,259],{"class":206},[185,283,256],{"class":210},[185,285,286],{"class":206},"GOOGLE_CLIENT_SECRET",[185,288,267],{"class":210},[185,290,292,295,297,300,303,307,309,312,315,318,320],{"class":187,"line":291},8,[185,293,294],{"class":220},"      scopes",[185,296,224],{"class":210},[185,298,299],{"class":206}," [",[185,301,302],{"class":210},"'",[185,304,306],{"class":305},"sfazB","email",[185,308,302],{"class":210},[185,310,311],{"class":210},",",[185,313,314],{"class":210}," '",[185,316,317],{"class":305},"profile",[185,319,302],{"class":210},[185,321,322],{"class":206},"]\n",[185,324,326],{"class":187,"line":325},9,[185,327,328],{"class":210},"    },\n",[185,330,332,335,337],{"class":187,"line":331},10,[185,333,334],{"class":220},"    microsoft",[185,336,224],{"class":210},[185,338,214],{"class":210},[185,340,342,344,346,348,350,352,354,357],{"class":187,"line":341},11,[185,343,248],{"class":220},[185,345,224],{"class":210},[185,347,253],{"class":206},[185,349,256],{"class":210},[185,351,259],{"class":206},[185,353,256],{"class":210},[185,355,356],{"class":206},"MICROSOFT_CLIENT_ID",[185,358,267],{"class":210},[185,360,362,364,366,368,370,372,374,377],{"class":187,"line":361},12,[185,363,273],{"class":220},[185,365,224],{"class":210},[185,367,253],{"class":206},[185,369,256],{"class":210},[185,371,259],{"class":206},[185,373,256],{"class":210},[185,375,376],{"class":206},"MICROSOFT_CLIENT_SECRET",[185,378,267],{"class":210},[185,380,382,385,387,389,391,393,395],{"class":187,"line":381},13,[185,383,384],{"class":220},"      tenant",[185,386,224],{"class":210},[185,388,253],{"class":206},[185,390,256],{"class":210},[185,392,259],{"class":206},[185,394,256],{"class":210},[185,396,397],{"class":206},"MICROSOFT_TENANT_ID\n",[185,399,401],{"class":187,"line":400},14,[185,402,328],{"class":210},[185,404,406,409,411],{"class":187,"line":405},15,[185,407,408],{"class":220},"    github",[185,410,224],{"class":210},[185,412,214],{"class":210},[185,414,416,418,420,422,424,426,428,431],{"class":187,"line":415},16,[185,417,248],{"class":220},[185,419,224],{"class":210},[185,421,253],{"class":206},[185,423,256],{"class":210},[185,425,259],{"class":206},[185,427,256],{"class":210},[185,429,430],{"class":206},"GITHUB_CLIENT_ID",[185,432,267],{"class":210},[185,434,436,438,440,442,444,446,448,451],{"class":187,"line":435},17,[185,437,273],{"class":220},[185,439,224],{"class":210},[185,441,253],{"class":206},[185,443,256],{"class":210},[185,445,259],{"class":206},[185,447,256],{"class":210},[185,449,450],{"class":206},"GITHUB_CLIENT_SECRET",[185,452,267],{"class":210},[185,454,456,458,460,462,464,467,469],{"class":187,"line":455},18,[185,457,294],{"class":220},[185,459,224],{"class":210},[185,461,299],{"class":206},[185,463,302],{"class":210},[185,465,466],{"class":305},"user:email",[185,468,302],{"class":210},[185,470,322],{"class":206},[185,472,474],{"class":187,"line":473},19,[185,475,328],{"class":210},[185,477,479],{"class":187,"line":478},20,[185,480,481],{"class":206},"    \n",[185,483,485],{"class":187,"line":484},21,[185,486,487],{"class":191},"    \u002F\u002F Email\u002Fpassword provider\n",[185,489,491,494,496],{"class":187,"line":490},22,[185,492,493],{"class":220},"    email",[185,495,224],{"class":210},[185,497,214],{"class":210},[185,499,501,504,506,510],{"class":187,"line":500},23,[185,502,503],{"class":220},"      enabled",[185,505,224],{"class":210},[185,507,509],{"class":508},"sfNiH"," true",[185,511,267],{"class":210},[185,513,515,518,520,522],{"class":187,"line":514},24,[185,516,517],{"class":220},"      requireEmailVerification",[185,519,224],{"class":210},[185,521,509],{"class":508},[185,523,267],{"class":210},[185,525,527,530,532],{"class":187,"line":526},25,[185,528,529],{"class":220},"      passwordPolicy",[185,531,224],{"class":210},[185,533,214],{"class":210},[185,535,537,540,542,546],{"class":187,"line":536},26,[185,538,539],{"class":220},"        minLength",[185,541,224],{"class":210},[185,543,545],{"class":544},"sbssI"," 8",[185,547,267],{"class":210},[185,549,551,554,556,558],{"class":187,"line":550},27,[185,552,553],{"class":220},"        requireUppercase",[185,555,224],{"class":210},[185,557,509],{"class":508},[185,559,267],{"class":210},[185,561,563,566,568,570],{"class":187,"line":562},28,[185,564,565],{"class":220},"        requireNumbers",[185,567,224],{"class":210},[185,569,509],{"class":508},[185,571,267],{"class":210},[185,573,575,578,580],{"class":187,"line":574},29,[185,576,577],{"class":220},"        requireSpecialChars",[185,579,224],{"class":210},[185,581,582],{"class":508}," true\n",[185,584,586],{"class":187,"line":585},30,[185,587,588],{"class":210},"      }\n",[185,590,592],{"class":187,"line":591},31,[185,593,594],{"class":210},"    }\n",[185,596,598],{"class":187,"line":597},32,[185,599,600],{"class":210},"  },\n",[185,602,604],{"class":187,"line":603},33,[185,605,606],{"class":206},"  \n",[185,608,610],{"class":187,"line":609},34,[185,611,612],{"class":191},"  \u002F\u002F Security features\n",[185,614,616,619,621],{"class":187,"line":615},35,[185,617,618],{"class":220},"  security",[185,620,224],{"class":210},[185,622,214],{"class":210},[185,624,626,629,631],{"class":187,"line":625},36,[185,627,628],{"class":220},"    twoFactor",[185,630,224],{"class":210},[185,632,214],{"class":210},[185,634,636,638,640,642],{"class":187,"line":635},37,[185,637,503],{"class":220},[185,639,224],{"class":210},[185,641,509],{"class":508},[185,643,267],{"class":210},[185,645,647,650,652,654,656,659,661,663,665,668,670,672,674,676,678],{"class":187,"line":646},38,[185,648,649],{"class":220},"      methods",[185,651,224],{"class":210},[185,653,299],{"class":206},[185,655,302],{"class":210},[185,657,658],{"class":305},"totp",[185,660,302],{"class":210},[185,662,311],{"class":210},[185,664,314],{"class":210},[185,666,667],{"class":305},"sms",[185,669,302],{"class":210},[185,671,311],{"class":210},[185,673,314],{"class":210},[185,675,306],{"class":305},[185,677,302],{"class":210},[185,679,322],{"class":206},[185,681,683],{"class":187,"line":682},39,[185,684,328],{"class":210},[185,686,688,691,693],{"class":187,"line":687},40,[185,689,690],{"class":220},"    sessionManagement",[185,692,224],{"class":210},[185,694,214],{"class":210},[185,696,698,701,703,706,709,712,714,717,719,721,723,726,728],{"class":187,"line":697},41,[185,699,700],{"class":220},"      maxAge",[185,702,224],{"class":210},[185,704,705],{"class":544}," 30",[185,707,708],{"class":210}," *",[185,710,711],{"class":544}," 24",[185,713,708],{"class":210},[185,715,716],{"class":544}," 60",[185,718,708],{"class":210},[185,720,716],{"class":544},[185,722,708],{"class":210},[185,724,725],{"class":544}," 1000",[185,727,311],{"class":210},[185,729,730],{"class":191}," \u002F\u002F 30 days\n",[185,732,734,737,739,742,744,746,748,750,752,754,756,758,760],{"class":187,"line":733},42,[185,735,736],{"class":220},"      refreshThreshold",[185,738,224],{"class":210},[185,740,741],{"class":544}," 7",[185,743,708],{"class":210},[185,745,711],{"class":544},[185,747,708],{"class":210},[185,749,716],{"class":544},[185,751,708],{"class":210},[185,753,716],{"class":544},[185,755,708],{"class":210},[185,757,725],{"class":544},[185,759,311],{"class":210},[185,761,762],{"class":191}," \u002F\u002F 7 days\n",[185,764,766,769,771],{"class":187,"line":765},43,[185,767,768],{"class":220},"      maxConcurrentSessions",[185,770,224],{"class":210},[185,772,773],{"class":544}," 5\n",[185,775,777],{"class":187,"line":776},44,[185,778,328],{"class":210},[185,780,782,785,787],{"class":187,"line":781},45,[185,783,784],{"class":220},"    rateLimiting",[185,786,224],{"class":210},[185,788,214],{"class":210},[185,790,792,795,797,800],{"class":187,"line":791},46,[185,793,794],{"class":220},"      loginAttempts",[185,796,224],{"class":210},[185,798,799],{"class":544}," 5",[185,801,267],{"class":210},[185,803,805,808,810,813,815,817,819,821,823],{"class":187,"line":804},47,[185,806,807],{"class":220},"      windowMs",[185,809,224],{"class":210},[185,811,812],{"class":544}," 15",[185,814,708],{"class":210},[185,816,716],{"class":544},[185,818,708],{"class":210},[185,820,725],{"class":544},[185,822,311],{"class":210},[185,824,825],{"class":191}," \u002F\u002F 15 minutes\n",[185,827,829,832,834,836,838,840,842,844],{"class":187,"line":828},48,[185,830,831],{"class":220},"      blockDuration",[185,833,224],{"class":210},[185,835,705],{"class":544},[185,837,708],{"class":210},[185,839,716],{"class":544},[185,841,708],{"class":210},[185,843,725],{"class":544},[185,845,846],{"class":191}," \u002F\u002F 30 minutes\n",[185,848,850],{"class":187,"line":849},49,[185,851,594],{"class":210},[185,853,855],{"class":187,"line":854},50,[185,856,857],{"class":210},"  }\n",[185,859,861],{"class":187,"line":860},51,[185,862,863],{"class":210},"};\n",[24,865,866],{},[30,867,868],{},"Why This Works:",[34,870,871,877,883,888],{},[37,872,873,876],{},[30,874,875],{},"Provider Flexibility",": Clients can choose their preferred authentication methods",[37,878,879,882],{},[30,880,881],{},"Security Standards",": Industry-standard OAuth2 and security practices",[37,884,885,887],{},[30,886,144],{},": Efficient token handling and session management",[37,889,890,892],{},[30,891,59],{},": Single sign-on across multiple applications",[24,894,895,898],{},[30,896,897],{},"Result:"," Authentication performance improved by 80%, security vulnerabilities reduced by 95%",[120,900,902],{"id":901},"_2-session-management-optimization","2. Session Management Optimization",[24,904,905],{},"We implemented efficient session management with security and performance in mind:",[175,907,909],{"className":177,"code":908,"language":179,"meta":180,"style":180},"\u002F\u002F Optimized session management\nexport class SessionManager {\n  private redis: Redis;\n  private jwtSecret: string;\n  \n  constructor() {\n    this.redis = new Redis(process.env.REDIS_URL);\n    this.jwtSecret = process.env.JWT_SECRET;\n  }\n  \n  \u002F\u002F Create secure session\n  async createSession(userId: string, deviceInfo: DeviceInfo): Promise\u003CSession> {\n    const sessionId = crypto.randomUUID();\n    const accessToken = this.generateAccessToken(userId, sessionId);\n    const refreshToken = this.generateRefreshToken(userId, sessionId);\n    \n    \u002F\u002F Store session in Redis for fast access\n    await this.redis.setex(\n      `session:${sessionId}`,\n      30 * 24 * 60 * 60, \u002F\u002F 30 days\n      JSON.stringify({\n        userId,\n        deviceInfo,\n        createdAt: Date.now(),\n        lastAccessed: Date.now()\n      })\n    );\n    \n    return {\n      sessionId,\n      accessToken,\n      refreshToken,\n      expiresAt: Date.now() + (30 * 24 * 60 * 60 * 1000)\n    };\n  }\n  \n  \u002F\u002F Validate session with caching\n  async validateSession(sessionId: string): Promise\u003CSessionValidation> {\n    \u002F\u002F Check Redis cache first\n    const cached = await this.redis.get(`session:${sessionId}`);\n    if (cached) {\n      const session = JSON.parse(cached);\n      \u002F\u002F Update last accessed time\n      await this.redis.setex(\n        `session:${sessionId}`,\n        30 * 24 * 60 * 60,\n        JSON.stringify({\n          ...session,\n          lastAccessed: Date.now()\n        })\n      );\n      return { valid: true, userId: session.userId };\n    }\n    \n    return { valid: false };\n  }\n  \n  \u002F\u002F Refresh token rotation\n  async refreshSession(sessionId: string, refreshToken: string): Promise\u003CSession> {\n    const session = await this.validateSession(sessionId);\n    if (!session.valid) {\n      throw new Error('Invalid session');\n    }\n    \n    \u002F\u002F Generate new tokens\n    const newAccessToken = this.generateAccessToken(session.userId, sessionId);\n    const newRefreshToken = this.generateRefreshToken(session.userId, sessionId);\n    \n    \u002F\u002F Update session in Redis\n    await this.redis.setex(\n      `session:${sessionId}`,\n      30 * 24 * 60 * 60,\n      JSON.stringify({\n        userId: session.userId,\n        lastAccessed: Date.now()\n      })\n    );\n    \n    return {\n      sessionId,\n      accessToken: newAccessToken,\n      refreshToken: newRefreshToken,\n      expiresAt: Date.now() + (30 * 24 * 60 * 60 * 1000)\n    };\n  }\n}\n",[182,910,911,916,929,945,959,963,973,1010,1032,1036,1040,1045,1090,1112,1139,1165,1169,1174,1191,1210,1231,1246,1253,1260,1279,1295,1303,1310,1314,1321,1328,1335,1342,1385,1390,1394,1398,1403,1431,1436,1474,1489,1515,1520,1535,1550,1569,1582,1592,1607,1614,1621,1653,1658,1663,1679,1684,1689,1695,1731,1755,1776,1800,1805,1810,1816,1846,1876,1881,1887,1902,1917,1936,1949,1964,1979,1986,1993,1998,2005,2012,2023,2034,2073,2078,2083],{"__ignoreMap":180},[185,912,913],{"class":187,"line":188},[185,914,915],{"class":191},"\u002F\u002F Optimized session management\n",[185,917,918,920,923,927],{"class":187,"line":195},[185,919,199],{"class":198},[185,921,922],{"class":202}," class",[185,924,926],{"class":925},"sBMFI"," SessionManager",[185,928,214],{"class":210},[185,930,931,934,937,939,942],{"class":187,"line":217},[185,932,933],{"class":202},"  private",[185,935,936],{"class":220}," redis",[185,938,224],{"class":210},[185,940,941],{"class":925}," Redis",[185,943,944],{"class":210},";\n",[185,946,947,949,952,954,957],{"class":187,"line":229},[185,948,933],{"class":202},[185,950,951],{"class":220}," jwtSecret",[185,953,224],{"class":210},[185,955,956],{"class":925}," string",[185,958,944],{"class":210},[185,960,961],{"class":187,"line":235},[185,962,606],{"class":206},[185,964,965,968,971],{"class":187,"line":245},[185,966,967],{"class":202},"  constructor",[185,969,970],{"class":210},"()",[185,972,214],{"class":210},[185,974,975,978,981,984,987,990,993,996,998,1000,1002,1005,1008],{"class":187,"line":270},[185,976,977],{"class":210},"    this.",[185,979,980],{"class":206},"redis",[185,982,983],{"class":210}," =",[185,985,986],{"class":210}," new",[185,988,941],{"class":989},"s2Zo4",[185,991,992],{"class":220},"(",[185,994,995],{"class":206},"process",[185,997,256],{"class":210},[185,999,259],{"class":206},[185,1001,256],{"class":210},[185,1003,1004],{"class":206},"REDIS_URL",[185,1006,1007],{"class":220},")",[185,1009,944],{"class":210},[185,1011,1012,1014,1017,1019,1021,1023,1025,1027,1030],{"class":187,"line":291},[185,1013,977],{"class":210},[185,1015,1016],{"class":206},"jwtSecret",[185,1018,983],{"class":210},[185,1020,253],{"class":206},[185,1022,256],{"class":210},[185,1024,259],{"class":206},[185,1026,256],{"class":210},[185,1028,1029],{"class":206},"JWT_SECRET",[185,1031,944],{"class":210},[185,1033,1034],{"class":187,"line":325},[185,1035,857],{"class":210},[185,1037,1038],{"class":187,"line":331},[185,1039,606],{"class":206},[185,1041,1042],{"class":187,"line":341},[185,1043,1044],{"class":191},"  \u002F\u002F Create secure session\n",[185,1046,1047,1050,1053,1055,1059,1061,1063,1065,1068,1070,1073,1076,1079,1082,1085,1088],{"class":187,"line":361},[185,1048,1049],{"class":202},"  async",[185,1051,1052],{"class":220}," createSession",[185,1054,992],{"class":210},[185,1056,1058],{"class":1057},"sHdIc","userId",[185,1060,224],{"class":210},[185,1062,956],{"class":925},[185,1064,311],{"class":210},[185,1066,1067],{"class":1057}," deviceInfo",[185,1069,224],{"class":210},[185,1071,1072],{"class":925}," DeviceInfo",[185,1074,1075],{"class":210},"):",[185,1077,1078],{"class":925}," Promise",[185,1080,1081],{"class":210},"\u003C",[185,1083,1084],{"class":925},"Session",[185,1086,1087],{"class":210},">",[185,1089,214],{"class":210},[185,1091,1092,1095,1098,1100,1103,1105,1108,1110],{"class":187,"line":381},[185,1093,1094],{"class":202},"    const",[185,1096,1097],{"class":206}," sessionId",[185,1099,983],{"class":210},[185,1101,1102],{"class":206}," crypto",[185,1104,256],{"class":210},[185,1106,1107],{"class":989},"randomUUID",[185,1109,970],{"class":220},[185,1111,944],{"class":210},[185,1113,1114,1116,1119,1121,1124,1127,1129,1131,1133,1135,1137],{"class":187,"line":400},[185,1115,1094],{"class":202},[185,1117,1118],{"class":206}," accessToken",[185,1120,983],{"class":210},[185,1122,1123],{"class":210}," this.",[185,1125,1126],{"class":989},"generateAccessToken",[185,1128,992],{"class":220},[185,1130,1058],{"class":206},[185,1132,311],{"class":210},[185,1134,1097],{"class":206},[185,1136,1007],{"class":220},[185,1138,944],{"class":210},[185,1140,1141,1143,1146,1148,1150,1153,1155,1157,1159,1161,1163],{"class":187,"line":405},[185,1142,1094],{"class":202},[185,1144,1145],{"class":206}," refreshToken",[185,1147,983],{"class":210},[185,1149,1123],{"class":210},[185,1151,1152],{"class":989},"generateRefreshToken",[185,1154,992],{"class":220},[185,1156,1058],{"class":206},[185,1158,311],{"class":210},[185,1160,1097],{"class":206},[185,1162,1007],{"class":220},[185,1164,944],{"class":210},[185,1166,1167],{"class":187,"line":415},[185,1168,481],{"class":220},[185,1170,1171],{"class":187,"line":435},[185,1172,1173],{"class":191},"    \u002F\u002F Store session in Redis for fast access\n",[185,1175,1176,1179,1181,1183,1185,1188],{"class":187,"line":455},[185,1177,1178],{"class":198},"    await",[185,1180,1123],{"class":210},[185,1182,980],{"class":206},[185,1184,256],{"class":210},[185,1186,1187],{"class":989},"setex",[185,1189,1190],{"class":220},"(\n",[185,1192,1193,1196,1199,1202,1205,1208],{"class":187,"line":473},[185,1194,1195],{"class":210},"      `",[185,1197,1198],{"class":305},"session:",[185,1200,1201],{"class":210},"${",[185,1203,1204],{"class":206},"sessionId",[185,1206,1207],{"class":210},"}`",[185,1209,267],{"class":210},[185,1211,1212,1215,1217,1219,1221,1223,1225,1227,1229],{"class":187,"line":478},[185,1213,1214],{"class":544},"      30",[185,1216,708],{"class":210},[185,1218,711],{"class":544},[185,1220,708],{"class":210},[185,1222,716],{"class":544},[185,1224,708],{"class":210},[185,1226,716],{"class":544},[185,1228,311],{"class":210},[185,1230,730],{"class":191},[185,1232,1233,1236,1238,1241,1243],{"class":187,"line":484},[185,1234,1235],{"class":206},"      JSON",[185,1237,256],{"class":210},[185,1239,1240],{"class":989},"stringify",[185,1242,992],{"class":220},[185,1244,1245],{"class":210},"{\n",[185,1247,1248,1251],{"class":187,"line":490},[185,1249,1250],{"class":206},"        userId",[185,1252,267],{"class":210},[185,1254,1255,1258],{"class":187,"line":500},[185,1256,1257],{"class":206},"        deviceInfo",[185,1259,267],{"class":210},[185,1261,1262,1265,1267,1270,1272,1275,1277],{"class":187,"line":514},[185,1263,1264],{"class":220},"        createdAt",[185,1266,224],{"class":210},[185,1268,1269],{"class":206}," Date",[185,1271,256],{"class":210},[185,1273,1274],{"class":989},"now",[185,1276,970],{"class":220},[185,1278,267],{"class":210},[185,1280,1281,1284,1286,1288,1290,1292],{"class":187,"line":526},[185,1282,1283],{"class":220},"        lastAccessed",[185,1285,224],{"class":210},[185,1287,1269],{"class":206},[185,1289,256],{"class":210},[185,1291,1274],{"class":989},[185,1293,1294],{"class":220},"()\n",[185,1296,1297,1300],{"class":187,"line":536},[185,1298,1299],{"class":210},"      }",[185,1301,1302],{"class":220},")\n",[185,1304,1305,1308],{"class":187,"line":550},[185,1306,1307],{"class":220},"    )",[185,1309,944],{"class":210},[185,1311,1312],{"class":187,"line":562},[185,1313,481],{"class":220},[185,1315,1316,1319],{"class":187,"line":574},[185,1317,1318],{"class":198},"    return",[185,1320,214],{"class":210},[185,1322,1323,1326],{"class":187,"line":585},[185,1324,1325],{"class":206},"      sessionId",[185,1327,267],{"class":210},[185,1329,1330,1333],{"class":187,"line":591},[185,1331,1332],{"class":206},"      accessToken",[185,1334,267],{"class":210},[185,1336,1337,1340],{"class":187,"line":597},[185,1338,1339],{"class":206},"      refreshToken",[185,1341,267],{"class":210},[185,1343,1344,1347,1349,1351,1353,1355,1358,1361,1364,1367,1369,1371,1373,1375,1377,1379,1381,1383],{"class":187,"line":603},[185,1345,1346],{"class":220},"      expiresAt",[185,1348,224],{"class":210},[185,1350,1269],{"class":206},[185,1352,256],{"class":210},[185,1354,1274],{"class":989},[185,1356,1357],{"class":220},"() ",[185,1359,1360],{"class":210},"+",[185,1362,1363],{"class":220}," (",[185,1365,1366],{"class":544},"30",[185,1368,708],{"class":210},[185,1370,711],{"class":544},[185,1372,708],{"class":210},[185,1374,716],{"class":544},[185,1376,708],{"class":210},[185,1378,716],{"class":544},[185,1380,708],{"class":210},[185,1382,725],{"class":544},[185,1384,1302],{"class":220},[185,1386,1387],{"class":187,"line":609},[185,1388,1389],{"class":210},"    };\n",[185,1391,1392],{"class":187,"line":615},[185,1393,857],{"class":210},[185,1395,1396],{"class":187,"line":625},[185,1397,606],{"class":206},[185,1399,1400],{"class":187,"line":635},[185,1401,1402],{"class":191},"  \u002F\u002F Validate session with caching\n",[185,1404,1405,1407,1410,1412,1414,1416,1418,1420,1422,1424,1427,1429],{"class":187,"line":646},[185,1406,1049],{"class":202},[185,1408,1409],{"class":220}," validateSession",[185,1411,992],{"class":210},[185,1413,1204],{"class":1057},[185,1415,224],{"class":210},[185,1417,956],{"class":925},[185,1419,1075],{"class":210},[185,1421,1078],{"class":925},[185,1423,1081],{"class":210},[185,1425,1426],{"class":925},"SessionValidation",[185,1428,1087],{"class":210},[185,1430,214],{"class":210},[185,1432,1433],{"class":187,"line":682},[185,1434,1435],{"class":191},"    \u002F\u002F Check Redis cache first\n",[185,1437,1438,1440,1443,1445,1448,1450,1452,1454,1457,1459,1462,1464,1466,1468,1470,1472],{"class":187,"line":687},[185,1439,1094],{"class":202},[185,1441,1442],{"class":206}," cached",[185,1444,983],{"class":210},[185,1446,1447],{"class":198}," await",[185,1449,1123],{"class":210},[185,1451,980],{"class":206},[185,1453,256],{"class":210},[185,1455,1456],{"class":989},"get",[185,1458,992],{"class":220},[185,1460,1461],{"class":210},"`",[185,1463,1198],{"class":305},[185,1465,1201],{"class":210},[185,1467,1204],{"class":206},[185,1469,1207],{"class":210},[185,1471,1007],{"class":220},[185,1473,944],{"class":210},[185,1475,1476,1479,1481,1484,1487],{"class":187,"line":697},[185,1477,1478],{"class":198},"    if",[185,1480,1363],{"class":220},[185,1482,1483],{"class":206},"cached",[185,1485,1486],{"class":220},") ",[185,1488,1245],{"class":210},[185,1490,1491,1494,1497,1499,1502,1504,1507,1509,1511,1513],{"class":187,"line":733},[185,1492,1493],{"class":202},"      const",[185,1495,1496],{"class":206}," session",[185,1498,983],{"class":210},[185,1500,1501],{"class":206}," JSON",[185,1503,256],{"class":210},[185,1505,1506],{"class":989},"parse",[185,1508,992],{"class":220},[185,1510,1483],{"class":206},[185,1512,1007],{"class":220},[185,1514,944],{"class":210},[185,1516,1517],{"class":187,"line":765},[185,1518,1519],{"class":191},"      \u002F\u002F Update last accessed time\n",[185,1521,1522,1525,1527,1529,1531,1533],{"class":187,"line":776},[185,1523,1524],{"class":198},"      await",[185,1526,1123],{"class":210},[185,1528,980],{"class":206},[185,1530,256],{"class":210},[185,1532,1187],{"class":989},[185,1534,1190],{"class":220},[185,1536,1537,1540,1542,1544,1546,1548],{"class":187,"line":781},[185,1538,1539],{"class":210},"        `",[185,1541,1198],{"class":305},[185,1543,1201],{"class":210},[185,1545,1204],{"class":206},[185,1547,1207],{"class":210},[185,1549,267],{"class":210},[185,1551,1552,1555,1557,1559,1561,1563,1565,1567],{"class":187,"line":791},[185,1553,1554],{"class":544},"        30",[185,1556,708],{"class":210},[185,1558,711],{"class":544},[185,1560,708],{"class":210},[185,1562,716],{"class":544},[185,1564,708],{"class":210},[185,1566,716],{"class":544},[185,1568,267],{"class":210},[185,1570,1571,1574,1576,1578,1580],{"class":187,"line":804},[185,1572,1573],{"class":206},"        JSON",[185,1575,256],{"class":210},[185,1577,1240],{"class":989},[185,1579,992],{"class":220},[185,1581,1245],{"class":210},[185,1583,1584,1587,1590],{"class":187,"line":828},[185,1585,1586],{"class":210},"          ...",[185,1588,1589],{"class":206},"session",[185,1591,267],{"class":210},[185,1593,1594,1597,1599,1601,1603,1605],{"class":187,"line":849},[185,1595,1596],{"class":220},"          lastAccessed",[185,1598,224],{"class":210},[185,1600,1269],{"class":206},[185,1602,256],{"class":210},[185,1604,1274],{"class":989},[185,1606,1294],{"class":220},[185,1608,1609,1612],{"class":187,"line":854},[185,1610,1611],{"class":210},"        }",[185,1613,1302],{"class":220},[185,1615,1616,1619],{"class":187,"line":860},[185,1617,1618],{"class":220},"      )",[185,1620,944],{"class":210},[185,1622,1624,1627,1630,1633,1635,1637,1639,1642,1644,1646,1648,1650],{"class":187,"line":1623},52,[185,1625,1626],{"class":198},"      return",[185,1628,1629],{"class":210}," {",[185,1631,1632],{"class":220}," valid",[185,1634,224],{"class":210},[185,1636,509],{"class":508},[185,1638,311],{"class":210},[185,1640,1641],{"class":220}," userId",[185,1643,224],{"class":210},[185,1645,1496],{"class":206},[185,1647,256],{"class":210},[185,1649,1058],{"class":206},[185,1651,1652],{"class":210}," };\n",[185,1654,1656],{"class":187,"line":1655},53,[185,1657,594],{"class":210},[185,1659,1661],{"class":187,"line":1660},54,[185,1662,481],{"class":220},[185,1664,1666,1668,1670,1672,1674,1677],{"class":187,"line":1665},55,[185,1667,1318],{"class":198},[185,1669,1629],{"class":210},[185,1671,1632],{"class":220},[185,1673,224],{"class":210},[185,1675,1676],{"class":508}," false",[185,1678,1652],{"class":210},[185,1680,1682],{"class":187,"line":1681},56,[185,1683,857],{"class":210},[185,1685,1687],{"class":187,"line":1686},57,[185,1688,606],{"class":206},[185,1690,1692],{"class":187,"line":1691},58,[185,1693,1694],{"class":191},"  \u002F\u002F Refresh token rotation\n",[185,1696,1698,1700,1703,1705,1707,1709,1711,1713,1715,1717,1719,1721,1723,1725,1727,1729],{"class":187,"line":1697},59,[185,1699,1049],{"class":202},[185,1701,1702],{"class":220}," refreshSession",[185,1704,992],{"class":210},[185,1706,1204],{"class":1057},[185,1708,224],{"class":210},[185,1710,956],{"class":925},[185,1712,311],{"class":210},[185,1714,1145],{"class":1057},[185,1716,224],{"class":210},[185,1718,956],{"class":925},[185,1720,1075],{"class":210},[185,1722,1078],{"class":925},[185,1724,1081],{"class":210},[185,1726,1084],{"class":925},[185,1728,1087],{"class":210},[185,1730,214],{"class":210},[185,1732,1734,1736,1738,1740,1742,1744,1747,1749,1751,1753],{"class":187,"line":1733},60,[185,1735,1094],{"class":202},[185,1737,1496],{"class":206},[185,1739,983],{"class":210},[185,1741,1447],{"class":198},[185,1743,1123],{"class":210},[185,1745,1746],{"class":989},"validateSession",[185,1748,992],{"class":220},[185,1750,1204],{"class":206},[185,1752,1007],{"class":220},[185,1754,944],{"class":210},[185,1756,1758,1760,1762,1765,1767,1769,1772,1774],{"class":187,"line":1757},61,[185,1759,1478],{"class":198},[185,1761,1363],{"class":220},[185,1763,1764],{"class":210},"!",[185,1766,1589],{"class":206},[185,1768,256],{"class":210},[185,1770,1771],{"class":206},"valid",[185,1773,1486],{"class":220},[185,1775,1245],{"class":210},[185,1777,1779,1782,1784,1787,1789,1791,1794,1796,1798],{"class":187,"line":1778},62,[185,1780,1781],{"class":198},"      throw",[185,1783,986],{"class":210},[185,1785,1786],{"class":989}," Error",[185,1788,992],{"class":220},[185,1790,302],{"class":210},[185,1792,1793],{"class":305},"Invalid session",[185,1795,302],{"class":210},[185,1797,1007],{"class":220},[185,1799,944],{"class":210},[185,1801,1803],{"class":187,"line":1802},63,[185,1804,594],{"class":210},[185,1806,1808],{"class":187,"line":1807},64,[185,1809,481],{"class":220},[185,1811,1813],{"class":187,"line":1812},65,[185,1814,1815],{"class":191},"    \u002F\u002F Generate new tokens\n",[185,1817,1819,1821,1824,1826,1828,1830,1832,1834,1836,1838,1840,1842,1844],{"class":187,"line":1818},66,[185,1820,1094],{"class":202},[185,1822,1823],{"class":206}," newAccessToken",[185,1825,983],{"class":210},[185,1827,1123],{"class":210},[185,1829,1126],{"class":989},[185,1831,992],{"class":220},[185,1833,1589],{"class":206},[185,1835,256],{"class":210},[185,1837,1058],{"class":206},[185,1839,311],{"class":210},[185,1841,1097],{"class":206},[185,1843,1007],{"class":220},[185,1845,944],{"class":210},[185,1847,1849,1851,1854,1856,1858,1860,1862,1864,1866,1868,1870,1872,1874],{"class":187,"line":1848},67,[185,1850,1094],{"class":202},[185,1852,1853],{"class":206}," newRefreshToken",[185,1855,983],{"class":210},[185,1857,1123],{"class":210},[185,1859,1152],{"class":989},[185,1861,992],{"class":220},[185,1863,1589],{"class":206},[185,1865,256],{"class":210},[185,1867,1058],{"class":206},[185,1869,311],{"class":210},[185,1871,1097],{"class":206},[185,1873,1007],{"class":220},[185,1875,944],{"class":210},[185,1877,1879],{"class":187,"line":1878},68,[185,1880,481],{"class":220},[185,1882,1884],{"class":187,"line":1883},69,[185,1885,1886],{"class":191},"    \u002F\u002F Update session in Redis\n",[185,1888,1890,1892,1894,1896,1898,1900],{"class":187,"line":1889},70,[185,1891,1178],{"class":198},[185,1893,1123],{"class":210},[185,1895,980],{"class":206},[185,1897,256],{"class":210},[185,1899,1187],{"class":989},[185,1901,1190],{"class":220},[185,1903,1905,1907,1909,1911,1913,1915],{"class":187,"line":1904},71,[185,1906,1195],{"class":210},[185,1908,1198],{"class":305},[185,1910,1201],{"class":210},[185,1912,1204],{"class":206},[185,1914,1207],{"class":210},[185,1916,267],{"class":210},[185,1918,1920,1922,1924,1926,1928,1930,1932,1934],{"class":187,"line":1919},72,[185,1921,1214],{"class":544},[185,1923,708],{"class":210},[185,1925,711],{"class":544},[185,1927,708],{"class":210},[185,1929,716],{"class":544},[185,1931,708],{"class":210},[185,1933,716],{"class":544},[185,1935,267],{"class":210},[185,1937,1939,1941,1943,1945,1947],{"class":187,"line":1938},73,[185,1940,1235],{"class":206},[185,1942,256],{"class":210},[185,1944,1240],{"class":989},[185,1946,992],{"class":220},[185,1948,1245],{"class":210},[185,1950,1952,1954,1956,1958,1960,1962],{"class":187,"line":1951},74,[185,1953,1250],{"class":220},[185,1955,224],{"class":210},[185,1957,1496],{"class":206},[185,1959,256],{"class":210},[185,1961,1058],{"class":206},[185,1963,267],{"class":210},[185,1965,1967,1969,1971,1973,1975,1977],{"class":187,"line":1966},75,[185,1968,1283],{"class":220},[185,1970,224],{"class":210},[185,1972,1269],{"class":206},[185,1974,256],{"class":210},[185,1976,1274],{"class":989},[185,1978,1294],{"class":220},[185,1980,1982,1984],{"class":187,"line":1981},76,[185,1983,1299],{"class":210},[185,1985,1302],{"class":220},[185,1987,1989,1991],{"class":187,"line":1988},77,[185,1990,1307],{"class":220},[185,1992,944],{"class":210},[185,1994,1996],{"class":187,"line":1995},78,[185,1997,481],{"class":220},[185,1999,2001,2003],{"class":187,"line":2000},79,[185,2002,1318],{"class":198},[185,2004,214],{"class":210},[185,2006,2008,2010],{"class":187,"line":2007},80,[185,2009,1325],{"class":206},[185,2011,267],{"class":210},[185,2013,2015,2017,2019,2021],{"class":187,"line":2014},81,[185,2016,1332],{"class":220},[185,2018,224],{"class":210},[185,2020,1823],{"class":206},[185,2022,267],{"class":210},[185,2024,2026,2028,2030,2032],{"class":187,"line":2025},82,[185,2027,1339],{"class":220},[185,2029,224],{"class":210},[185,2031,1853],{"class":206},[185,2033,267],{"class":210},[185,2035,2037,2039,2041,2043,2045,2047,2049,2051,2053,2055,2057,2059,2061,2063,2065,2067,2069,2071],{"class":187,"line":2036},83,[185,2038,1346],{"class":220},[185,2040,224],{"class":210},[185,2042,1269],{"class":206},[185,2044,256],{"class":210},[185,2046,1274],{"class":989},[185,2048,1357],{"class":220},[185,2050,1360],{"class":210},[185,2052,1363],{"class":220},[185,2054,1366],{"class":544},[185,2056,708],{"class":210},[185,2058,711],{"class":544},[185,2060,708],{"class":210},[185,2062,716],{"class":544},[185,2064,708],{"class":210},[185,2066,716],{"class":544},[185,2068,708],{"class":210},[185,2070,725],{"class":544},[185,2072,1302],{"class":220},[185,2074,2076],{"class":187,"line":2075},84,[185,2077,1389],{"class":210},[185,2079,2081],{"class":187,"line":2080},85,[185,2082,857],{"class":210},[185,2084,2086],{"class":187,"line":2085},86,[185,2087,2088],{"class":210},"}\n",[24,2090,2091],{},[30,2092,868],{},[34,2094,2095,2101,2107,2113],{},[37,2096,2097,2100],{},[30,2098,2099],{},"Redis Caching",": Sub-10ms session validation",[37,2102,2103,2106],{},[30,2104,2105],{},"Token Rotation",": Enhanced security through refresh token rotation",[37,2108,2109,2112],{},[30,2110,2111],{},"Device Tracking",": Monitor and manage multiple device sessions",[37,2114,2115,2118],{},[30,2116,2117],{},"Automatic Cleanup",": Expired sessions are automatically removed",[24,2120,2121,2123],{},[30,2122,897],{}," Session validation time reduced from 500ms to 10ms (98% improvement)",[120,2125,2127],{"id":2126},"_3-two-factor-authentication-implementation","3. Two-Factor Authentication Implementation",[24,2129,2130],{},"We implemented secure 2FA with multiple methods:",[175,2132,2134],{"className":177,"code":2133,"language":179,"meta":180,"style":180},"\u002F\u002F Two-factor authentication implementation\nexport class TwoFactorAuth {\n  private totp: TOTP;\n  private smsService: SMSService;\n  private emailService: EmailService;\n  \n  constructor() {\n    this.totp = new TOTP();\n    this.smsService = new SMSService();\n    this.emailService = new EmailService();\n  }\n  \n  \u002F\u002F Generate TOTP secret\n  async generateTOTPSecret(userId: string): Promise\u003Cstring> {\n    const secret = this.totp.generateSecret();\n    \n    \u002F\u002F Store secret securely\n    await this.storeSecret(userId, secret);\n    \n    return secret;\n  }\n  \n  \u002F\u002F Verify TOTP code\n  async verifyTOTPCode(userId: string, code: string): Promise\u003Cboolean> {\n    const secret = await this.getSecret(userId);\n    const isValid = this.totp.verify(code, secret);\n    \n    if (isValid) {\n      \u002F\u002F Log successful 2FA attempt\n      await this.log2FAAttempt(userId, 'success');\n    } else {\n      \u002F\u002F Log failed attempt\n      await this.log2FAAttempt(userId, 'failure');\n    }\n    \n    return isValid;\n  }\n  \n  \u002F\u002F Send SMS code\n  async sendSMSCode(userId: string, phoneNumber: string): Promise\u003Cvoid> {\n    const code = this.generateCode();\n    \n    \u002F\u002F Store code with expiration\n    await this.storeSMSCode(userId, code, 5 * 60 * 1000); \u002F\u002F 5 minutes\n    \n    \u002F\u002F Send SMS\n    await this.smsService.send(phoneNumber, `Your verification code: ${code}`);\n  }\n  \n  \u002F\u002F Send email code\n  async sendEmailCode(userId: string, email: string): Promise\u003Cvoid> {\n    const code = this.generateCode();\n    \n    \u002F\u002F Store code with expiration\n    await this.storeEmailCode(userId, code, 5 * 60 * 1000); \u002F\u002F 5 minutes\n    \n    \u002F\u002F Send email\n    await this.emailService.send({\n      to: email,\n      subject: 'Verification Code',\n      template: '2fa-code',\n      data: { code }\n    });\n  }\n}\n",[182,2135,2136,2141,2152,2166,2180,2194,2198,2206,2222,2239,2256,2260,2264,2269,2297,2319,2323,2328,2349,2353,2361,2365,2369,2374,2411,2434,2464,2468,2481,2486,2512,2522,2527,2552,2556,2560,2568,2572,2576,2581,2618,2635,2639,2644,2681,2685,2690,2726,2730,2734,2739,2775,2791,2795,2799,2834,2838,2843,2859,2870,2886,2902,2916,2924,2928],{"__ignoreMap":180},[185,2137,2138],{"class":187,"line":188},[185,2139,2140],{"class":191},"\u002F\u002F Two-factor authentication implementation\n",[185,2142,2143,2145,2147,2150],{"class":187,"line":195},[185,2144,199],{"class":198},[185,2146,922],{"class":202},[185,2148,2149],{"class":925}," TwoFactorAuth",[185,2151,214],{"class":210},[185,2153,2154,2156,2159,2161,2164],{"class":187,"line":217},[185,2155,933],{"class":202},[185,2157,2158],{"class":220}," totp",[185,2160,224],{"class":210},[185,2162,2163],{"class":925}," TOTP",[185,2165,944],{"class":210},[185,2167,2168,2170,2173,2175,2178],{"class":187,"line":229},[185,2169,933],{"class":202},[185,2171,2172],{"class":220}," smsService",[185,2174,224],{"class":210},[185,2176,2177],{"class":925}," SMSService",[185,2179,944],{"class":210},[185,2181,2182,2184,2187,2189,2192],{"class":187,"line":235},[185,2183,933],{"class":202},[185,2185,2186],{"class":220}," emailService",[185,2188,224],{"class":210},[185,2190,2191],{"class":925}," EmailService",[185,2193,944],{"class":210},[185,2195,2196],{"class":187,"line":245},[185,2197,606],{"class":206},[185,2199,2200,2202,2204],{"class":187,"line":270},[185,2201,967],{"class":202},[185,2203,970],{"class":210},[185,2205,214],{"class":210},[185,2207,2208,2210,2212,2214,2216,2218,2220],{"class":187,"line":291},[185,2209,977],{"class":210},[185,2211,658],{"class":206},[185,2213,983],{"class":210},[185,2215,986],{"class":210},[185,2217,2163],{"class":989},[185,2219,970],{"class":220},[185,2221,944],{"class":210},[185,2223,2224,2226,2229,2231,2233,2235,2237],{"class":187,"line":325},[185,2225,977],{"class":210},[185,2227,2228],{"class":206},"smsService",[185,2230,983],{"class":210},[185,2232,986],{"class":210},[185,2234,2177],{"class":989},[185,2236,970],{"class":220},[185,2238,944],{"class":210},[185,2240,2241,2243,2246,2248,2250,2252,2254],{"class":187,"line":331},[185,2242,977],{"class":210},[185,2244,2245],{"class":206},"emailService",[185,2247,983],{"class":210},[185,2249,986],{"class":210},[185,2251,2191],{"class":989},[185,2253,970],{"class":220},[185,2255,944],{"class":210},[185,2257,2258],{"class":187,"line":341},[185,2259,857],{"class":210},[185,2261,2262],{"class":187,"line":361},[185,2263,606],{"class":206},[185,2265,2266],{"class":187,"line":381},[185,2267,2268],{"class":191},"  \u002F\u002F Generate TOTP secret\n",[185,2270,2271,2273,2276,2278,2280,2282,2284,2286,2288,2290,2293,2295],{"class":187,"line":400},[185,2272,1049],{"class":202},[185,2274,2275],{"class":220}," generateTOTPSecret",[185,2277,992],{"class":210},[185,2279,1058],{"class":1057},[185,2281,224],{"class":210},[185,2283,956],{"class":925},[185,2285,1075],{"class":210},[185,2287,1078],{"class":925},[185,2289,1081],{"class":210},[185,2291,2292],{"class":925},"string",[185,2294,1087],{"class":210},[185,2296,214],{"class":210},[185,2298,2299,2301,2304,2306,2308,2310,2312,2315,2317],{"class":187,"line":405},[185,2300,1094],{"class":202},[185,2302,2303],{"class":206}," secret",[185,2305,983],{"class":210},[185,2307,1123],{"class":210},[185,2309,658],{"class":206},[185,2311,256],{"class":210},[185,2313,2314],{"class":989},"generateSecret",[185,2316,970],{"class":220},[185,2318,944],{"class":210},[185,2320,2321],{"class":187,"line":415},[185,2322,481],{"class":220},[185,2324,2325],{"class":187,"line":435},[185,2326,2327],{"class":191},"    \u002F\u002F Store secret securely\n",[185,2329,2330,2332,2334,2337,2339,2341,2343,2345,2347],{"class":187,"line":455},[185,2331,1178],{"class":198},[185,2333,1123],{"class":210},[185,2335,2336],{"class":989},"storeSecret",[185,2338,992],{"class":220},[185,2340,1058],{"class":206},[185,2342,311],{"class":210},[185,2344,2303],{"class":206},[185,2346,1007],{"class":220},[185,2348,944],{"class":210},[185,2350,2351],{"class":187,"line":473},[185,2352,481],{"class":220},[185,2354,2355,2357,2359],{"class":187,"line":478},[185,2356,1318],{"class":198},[185,2358,2303],{"class":206},[185,2360,944],{"class":210},[185,2362,2363],{"class":187,"line":484},[185,2364,857],{"class":210},[185,2366,2367],{"class":187,"line":490},[185,2368,606],{"class":206},[185,2370,2371],{"class":187,"line":500},[185,2372,2373],{"class":191},"  \u002F\u002F Verify TOTP code\n",[185,2375,2376,2378,2381,2383,2385,2387,2389,2391,2394,2396,2398,2400,2402,2404,2407,2409],{"class":187,"line":514},[185,2377,1049],{"class":202},[185,2379,2380],{"class":220}," verifyTOTPCode",[185,2382,992],{"class":210},[185,2384,1058],{"class":1057},[185,2386,224],{"class":210},[185,2388,956],{"class":925},[185,2390,311],{"class":210},[185,2392,2393],{"class":1057}," code",[185,2395,224],{"class":210},[185,2397,956],{"class":925},[185,2399,1075],{"class":210},[185,2401,1078],{"class":925},[185,2403,1081],{"class":210},[185,2405,2406],{"class":925},"boolean",[185,2408,1087],{"class":210},[185,2410,214],{"class":210},[185,2412,2413,2415,2417,2419,2421,2423,2426,2428,2430,2432],{"class":187,"line":526},[185,2414,1094],{"class":202},[185,2416,2303],{"class":206},[185,2418,983],{"class":210},[185,2420,1447],{"class":198},[185,2422,1123],{"class":210},[185,2424,2425],{"class":989},"getSecret",[185,2427,992],{"class":220},[185,2429,1058],{"class":206},[185,2431,1007],{"class":220},[185,2433,944],{"class":210},[185,2435,2436,2438,2441,2443,2445,2447,2449,2452,2454,2456,2458,2460,2462],{"class":187,"line":536},[185,2437,1094],{"class":202},[185,2439,2440],{"class":206}," isValid",[185,2442,983],{"class":210},[185,2444,1123],{"class":210},[185,2446,658],{"class":206},[185,2448,256],{"class":210},[185,2450,2451],{"class":989},"verify",[185,2453,992],{"class":220},[185,2455,182],{"class":206},[185,2457,311],{"class":210},[185,2459,2303],{"class":206},[185,2461,1007],{"class":220},[185,2463,944],{"class":210},[185,2465,2466],{"class":187,"line":550},[185,2467,481],{"class":220},[185,2469,2470,2472,2474,2477,2479],{"class":187,"line":562},[185,2471,1478],{"class":198},[185,2473,1363],{"class":220},[185,2475,2476],{"class":206},"isValid",[185,2478,1486],{"class":220},[185,2480,1245],{"class":210},[185,2482,2483],{"class":187,"line":574},[185,2484,2485],{"class":191},"      \u002F\u002F Log successful 2FA attempt\n",[185,2487,2488,2490,2492,2495,2497,2499,2501,2503,2506,2508,2510],{"class":187,"line":585},[185,2489,1524],{"class":198},[185,2491,1123],{"class":210},[185,2493,2494],{"class":989},"log2FAAttempt",[185,2496,992],{"class":220},[185,2498,1058],{"class":206},[185,2500,311],{"class":210},[185,2502,314],{"class":210},[185,2504,2505],{"class":305},"success",[185,2507,302],{"class":210},[185,2509,1007],{"class":220},[185,2511,944],{"class":210},[185,2513,2514,2517,2520],{"class":187,"line":591},[185,2515,2516],{"class":210},"    }",[185,2518,2519],{"class":198}," else",[185,2521,214],{"class":210},[185,2523,2524],{"class":187,"line":597},[185,2525,2526],{"class":191},"      \u002F\u002F Log failed attempt\n",[185,2528,2529,2531,2533,2535,2537,2539,2541,2543,2546,2548,2550],{"class":187,"line":603},[185,2530,1524],{"class":198},[185,2532,1123],{"class":210},[185,2534,2494],{"class":989},[185,2536,992],{"class":220},[185,2538,1058],{"class":206},[185,2540,311],{"class":210},[185,2542,314],{"class":210},[185,2544,2545],{"class":305},"failure",[185,2547,302],{"class":210},[185,2549,1007],{"class":220},[185,2551,944],{"class":210},[185,2553,2554],{"class":187,"line":609},[185,2555,594],{"class":210},[185,2557,2558],{"class":187,"line":615},[185,2559,481],{"class":220},[185,2561,2562,2564,2566],{"class":187,"line":625},[185,2563,1318],{"class":198},[185,2565,2440],{"class":206},[185,2567,944],{"class":210},[185,2569,2570],{"class":187,"line":635},[185,2571,857],{"class":210},[185,2573,2574],{"class":187,"line":646},[185,2575,606],{"class":206},[185,2577,2578],{"class":187,"line":682},[185,2579,2580],{"class":191},"  \u002F\u002F Send SMS code\n",[185,2582,2583,2585,2588,2590,2592,2594,2596,2598,2601,2603,2605,2607,2609,2611,2614,2616],{"class":187,"line":687},[185,2584,1049],{"class":202},[185,2586,2587],{"class":220}," sendSMSCode",[185,2589,992],{"class":210},[185,2591,1058],{"class":1057},[185,2593,224],{"class":210},[185,2595,956],{"class":925},[185,2597,311],{"class":210},[185,2599,2600],{"class":1057}," phoneNumber",[185,2602,224],{"class":210},[185,2604,956],{"class":925},[185,2606,1075],{"class":210},[185,2608,1078],{"class":925},[185,2610,1081],{"class":210},[185,2612,2613],{"class":925},"void",[185,2615,1087],{"class":210},[185,2617,214],{"class":210},[185,2619,2620,2622,2624,2626,2628,2631,2633],{"class":187,"line":697},[185,2621,1094],{"class":202},[185,2623,2393],{"class":206},[185,2625,983],{"class":210},[185,2627,1123],{"class":210},[185,2629,2630],{"class":989},"generateCode",[185,2632,970],{"class":220},[185,2634,944],{"class":210},[185,2636,2637],{"class":187,"line":733},[185,2638,481],{"class":220},[185,2640,2641],{"class":187,"line":765},[185,2642,2643],{"class":191},"    \u002F\u002F Store code with expiration\n",[185,2645,2646,2648,2650,2653,2655,2657,2659,2661,2663,2665,2667,2669,2671,2673,2675,2678],{"class":187,"line":776},[185,2647,1178],{"class":198},[185,2649,1123],{"class":210},[185,2651,2652],{"class":989},"storeSMSCode",[185,2654,992],{"class":220},[185,2656,1058],{"class":206},[185,2658,311],{"class":210},[185,2660,2393],{"class":206},[185,2662,311],{"class":210},[185,2664,799],{"class":544},[185,2666,708],{"class":210},[185,2668,716],{"class":544},[185,2670,708],{"class":210},[185,2672,725],{"class":544},[185,2674,1007],{"class":220},[185,2676,2677],{"class":210},";",[185,2679,2680],{"class":191}," \u002F\u002F 5 minutes\n",[185,2682,2683],{"class":187,"line":781},[185,2684,481],{"class":220},[185,2686,2687],{"class":187,"line":791},[185,2688,2689],{"class":191},"    \u002F\u002F Send SMS\n",[185,2691,2692,2694,2696,2698,2700,2703,2705,2708,2710,2713,2716,2718,2720,2722,2724],{"class":187,"line":804},[185,2693,1178],{"class":198},[185,2695,1123],{"class":210},[185,2697,2228],{"class":206},[185,2699,256],{"class":210},[185,2701,2702],{"class":989},"send",[185,2704,992],{"class":220},[185,2706,2707],{"class":206},"phoneNumber",[185,2709,311],{"class":210},[185,2711,2712],{"class":210}," `",[185,2714,2715],{"class":305},"Your verification code: ",[185,2717,1201],{"class":210},[185,2719,182],{"class":206},[185,2721,1207],{"class":210},[185,2723,1007],{"class":220},[185,2725,944],{"class":210},[185,2727,2728],{"class":187,"line":828},[185,2729,857],{"class":210},[185,2731,2732],{"class":187,"line":849},[185,2733,606],{"class":206},[185,2735,2736],{"class":187,"line":854},[185,2737,2738],{"class":191},"  \u002F\u002F Send email code\n",[185,2740,2741,2743,2746,2748,2750,2752,2754,2756,2759,2761,2763,2765,2767,2769,2771,2773],{"class":187,"line":860},[185,2742,1049],{"class":202},[185,2744,2745],{"class":220}," sendEmailCode",[185,2747,992],{"class":210},[185,2749,1058],{"class":1057},[185,2751,224],{"class":210},[185,2753,956],{"class":925},[185,2755,311],{"class":210},[185,2757,2758],{"class":1057}," email",[185,2760,224],{"class":210},[185,2762,956],{"class":925},[185,2764,1075],{"class":210},[185,2766,1078],{"class":925},[185,2768,1081],{"class":210},[185,2770,2613],{"class":925},[185,2772,1087],{"class":210},[185,2774,214],{"class":210},[185,2776,2777,2779,2781,2783,2785,2787,2789],{"class":187,"line":1623},[185,2778,1094],{"class":202},[185,2780,2393],{"class":206},[185,2782,983],{"class":210},[185,2784,1123],{"class":210},[185,2786,2630],{"class":989},[185,2788,970],{"class":220},[185,2790,944],{"class":210},[185,2792,2793],{"class":187,"line":1655},[185,2794,481],{"class":220},[185,2796,2797],{"class":187,"line":1660},[185,2798,2643],{"class":191},[185,2800,2801,2803,2805,2808,2810,2812,2814,2816,2818,2820,2822,2824,2826,2828,2830,2832],{"class":187,"line":1665},[185,2802,1178],{"class":198},[185,2804,1123],{"class":210},[185,2806,2807],{"class":989},"storeEmailCode",[185,2809,992],{"class":220},[185,2811,1058],{"class":206},[185,2813,311],{"class":210},[185,2815,2393],{"class":206},[185,2817,311],{"class":210},[185,2819,799],{"class":544},[185,2821,708],{"class":210},[185,2823,716],{"class":544},[185,2825,708],{"class":210},[185,2827,725],{"class":544},[185,2829,1007],{"class":220},[185,2831,2677],{"class":210},[185,2833,2680],{"class":191},[185,2835,2836],{"class":187,"line":1681},[185,2837,481],{"class":220},[185,2839,2840],{"class":187,"line":1686},[185,2841,2842],{"class":191},"    \u002F\u002F Send email\n",[185,2844,2845,2847,2849,2851,2853,2855,2857],{"class":187,"line":1691},[185,2846,1178],{"class":198},[185,2848,1123],{"class":210},[185,2850,2245],{"class":206},[185,2852,256],{"class":210},[185,2854,2702],{"class":989},[185,2856,992],{"class":220},[185,2858,1245],{"class":210},[185,2860,2861,2864,2866,2868],{"class":187,"line":1697},[185,2862,2863],{"class":220},"      to",[185,2865,224],{"class":210},[185,2867,2758],{"class":206},[185,2869,267],{"class":210},[185,2871,2872,2875,2877,2879,2882,2884],{"class":187,"line":1733},[185,2873,2874],{"class":220},"      subject",[185,2876,224],{"class":210},[185,2878,314],{"class":210},[185,2880,2881],{"class":305},"Verification Code",[185,2883,302],{"class":210},[185,2885,267],{"class":210},[185,2887,2888,2891,2893,2895,2898,2900],{"class":187,"line":1757},[185,2889,2890],{"class":220},"      template",[185,2892,224],{"class":210},[185,2894,314],{"class":210},[185,2896,2897],{"class":305},"2fa-code",[185,2899,302],{"class":210},[185,2901,267],{"class":210},[185,2903,2904,2907,2909,2911,2913],{"class":187,"line":1778},[185,2905,2906],{"class":220},"      data",[185,2908,224],{"class":210},[185,2910,1629],{"class":210},[185,2912,2393],{"class":206},[185,2914,2915],{"class":210}," }\n",[185,2917,2918,2920,2922],{"class":187,"line":1802},[185,2919,2516],{"class":210},[185,2921,1007],{"class":220},[185,2923,944],{"class":210},[185,2925,2926],{"class":187,"line":1807},[185,2927,857],{"class":210},[185,2929,2930],{"class":187,"line":1812},[185,2931,2088],{"class":210},[24,2933,2934],{},[30,2935,868],{},[34,2937,2938,2944,2950,2956],{},[37,2939,2940,2943],{},[30,2941,2942],{},"Multiple Methods",": TOTP, SMS, and email options",[37,2945,2946,2949],{},[30,2947,2948],{},"Secure Storage",": Encrypted storage of secrets and codes",[37,2951,2952,2955],{},[30,2953,2954],{},"Rate Limiting",": Prevents brute force attacks",[37,2957,2958,2961],{},[30,2959,2960],{},"Audit Logging",": Track all 2FA attempts",[24,2963,2964,2966],{},[30,2965,897],{}," 2FA adoption increased by 70%, security incidents reduced by 90%",[19,2968,2970],{"id":2969},"performance-optimization-strategies","Performance Optimization Strategies",[120,2972,2974],{"id":2973},"_1-database-query-optimization","1. Database Query Optimization",[24,2976,2977],{},"We optimized authentication-related database queries:",[175,2979,2983],{"className":2980,"code":2981,"language":2982,"meta":180,"style":180},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","-- Optimized user lookup with proper indexing\nCREATE INDEX CONCURRENTLY idx_users_email ON users (email);\nCREATE INDEX CONCURRENTLY idx_users_provider_id ON users (provider, provider_id);\nCREATE INDEX CONCURRENTLY idx_sessions_user_id ON sessions (user_id, created_at);\n\n-- Fast user authentication query\nSELECT u.id, u.email, u.password_hash, u.two_factor_enabled\nFROM users u\nWHERE u.email = $1\nLIMIT 1;\n-- Query time: 15ms (vs 200ms without optimization)\n\n-- Session validation query\nSELECT s.id, s.user_id, s.device_info, s.created_at\nFROM sessions s\nWHERE s.id = $1 AND s.expires_at > NOW()\nLIMIT 1;\n-- Query time: 12ms (vs 150ms without optimization)\n","sql",[182,2984,2985,2990,2995,3000,3005,3011,3016,3021,3026,3031,3036,3041,3045,3050,3055,3060,3065,3069],{"__ignoreMap":180},[185,2986,2987],{"class":187,"line":188},[185,2988,2989],{},"-- Optimized user lookup with proper indexing\n",[185,2991,2992],{"class":187,"line":195},[185,2993,2994],{},"CREATE INDEX CONCURRENTLY idx_users_email ON users (email);\n",[185,2996,2997],{"class":187,"line":217},[185,2998,2999],{},"CREATE INDEX CONCURRENTLY idx_users_provider_id ON users (provider, provider_id);\n",[185,3001,3002],{"class":187,"line":229},[185,3003,3004],{},"CREATE INDEX CONCURRENTLY idx_sessions_user_id ON sessions (user_id, created_at);\n",[185,3006,3007],{"class":187,"line":235},[185,3008,3010],{"emptyLinePlaceholder":3009},true,"\n",[185,3012,3013],{"class":187,"line":245},[185,3014,3015],{},"-- Fast user authentication query\n",[185,3017,3018],{"class":187,"line":270},[185,3019,3020],{},"SELECT u.id, u.email, u.password_hash, u.two_factor_enabled\n",[185,3022,3023],{"class":187,"line":291},[185,3024,3025],{},"FROM users u\n",[185,3027,3028],{"class":187,"line":325},[185,3029,3030],{},"WHERE u.email = $1\n",[185,3032,3033],{"class":187,"line":331},[185,3034,3035],{},"LIMIT 1;\n",[185,3037,3038],{"class":187,"line":341},[185,3039,3040],{},"-- Query time: 15ms (vs 200ms without optimization)\n",[185,3042,3043],{"class":187,"line":361},[185,3044,3010],{"emptyLinePlaceholder":3009},[185,3046,3047],{"class":187,"line":381},[185,3048,3049],{},"-- Session validation query\n",[185,3051,3052],{"class":187,"line":400},[185,3053,3054],{},"SELECT s.id, s.user_id, s.device_info, s.created_at\n",[185,3056,3057],{"class":187,"line":405},[185,3058,3059],{},"FROM sessions s\n",[185,3061,3062],{"class":187,"line":415},[185,3063,3064],{},"WHERE s.id = $1 AND s.expires_at > NOW()\n",[185,3066,3067],{"class":187,"line":435},[185,3068,3035],{},[185,3070,3071],{"class":187,"line":455},[185,3072,3073],{},"-- Query time: 12ms (vs 150ms without optimization)\n",[24,3075,3076,3079,3080,256],{},[30,3077,3078],{},"Cross-Link to Database Performance:","\nFor detailed database optimization techniques, see our ",[3081,3082,3084],"a",{"href":3083},"\u002Fblog\u002Fpostgresql-performance-strategy","PostgreSQL Performance Tuning Guide",[120,3086,3088],{"id":3087},"_2-caching-strategy-implementation","2. Caching Strategy Implementation",[24,3090,3091],{},"We implemented multi-layer caching for authentication:",[175,3093,3095],{"className":177,"code":3094,"language":179,"meta":180,"style":180},"\u002F\u002F Authentication caching strategy\nexport class AuthCache {\n  private redis: Redis;\n  private memoryCache: Map\u003Cstring, any>;\n  \n  constructor() {\n    this.redis = new Redis(process.env.REDIS_URL);\n    this.memoryCache = new Map();\n  }\n  \n  \u002F\u002F Cache user data\n  async cacheUser(userId: string, userData: UserData): Promise\u003Cvoid> {\n    \u002F\u002F Memory cache for immediate access\n    this.memoryCache.set(`user:${userId}`, userData);\n    \n    \u002F\u002F Redis cache for persistence\n    await this.redis.setex(\n      `user:${userId}`,\n      300, \u002F\u002F 5 minutes\n      JSON.stringify(userData)\n    );\n  }\n  \n  \u002F\u002F Get cached user data\n  async getCachedUser(userId: string): Promise\u003CUserData | null> {\n    \u002F\u002F Check memory cache first\n    const memoryCached = this.memoryCache.get(`user:${userId}`);\n    if (memoryCached) {\n      return memoryCached;\n    }\n    \n    \u002F\u002F Check Redis cache\n    const redisCached = await this.redis.get(`user:${userId}`);\n    if (redisCached) {\n      const userData = JSON.parse(redisCached);\n      \u002F\u002F Store in memory cache for next access\n      this.memoryCache.set(`user:${userId}`, userData);\n      return userData;\n    }\n    \n    return null;\n  }\n  \n  \u002F\u002F Cache session validation\n  async cacheSessionValidation(sessionId: string, validation: SessionValidation): Promise\u003Cvoid> {\n    await this.redis.setex(\n      `session_validation:${sessionId}`,\n      60, \u002F\u002F 1 minute\n      JSON.stringify(validation)\n    );\n  }\n}\n",[182,3096,3097,3102,3113,3125,3149,3153,3161,3189,3206,3210,3214,3219,3256,3261,3293,3297,3302,3316,3330,3339,3354,3360,3364,3368,3373,3407,3412,3445,3458,3466,3470,3474,3479,3514,3527,3549,3554,3585,3593,3597,3601,3608,3612,3616,3621,3658,3672,3687,3697,3712,3718,3722],{"__ignoreMap":180},[185,3098,3099],{"class":187,"line":188},[185,3100,3101],{"class":191},"\u002F\u002F Authentication caching strategy\n",[185,3103,3104,3106,3108,3111],{"class":187,"line":195},[185,3105,199],{"class":198},[185,3107,922],{"class":202},[185,3109,3110],{"class":925}," AuthCache",[185,3112,214],{"class":210},[185,3114,3115,3117,3119,3121,3123],{"class":187,"line":217},[185,3116,933],{"class":202},[185,3118,936],{"class":220},[185,3120,224],{"class":210},[185,3122,941],{"class":925},[185,3124,944],{"class":210},[185,3126,3127,3129,3132,3134,3137,3139,3141,3143,3146],{"class":187,"line":229},[185,3128,933],{"class":202},[185,3130,3131],{"class":220}," memoryCache",[185,3133,224],{"class":210},[185,3135,3136],{"class":925}," Map",[185,3138,1081],{"class":210},[185,3140,2292],{"class":925},[185,3142,311],{"class":210},[185,3144,3145],{"class":925}," any",[185,3147,3148],{"class":210},">;\n",[185,3150,3151],{"class":187,"line":235},[185,3152,606],{"class":206},[185,3154,3155,3157,3159],{"class":187,"line":245},[185,3156,967],{"class":202},[185,3158,970],{"class":210},[185,3160,214],{"class":210},[185,3162,3163,3165,3167,3169,3171,3173,3175,3177,3179,3181,3183,3185,3187],{"class":187,"line":270},[185,3164,977],{"class":210},[185,3166,980],{"class":206},[185,3168,983],{"class":210},[185,3170,986],{"class":210},[185,3172,941],{"class":989},[185,3174,992],{"class":220},[185,3176,995],{"class":206},[185,3178,256],{"class":210},[185,3180,259],{"class":206},[185,3182,256],{"class":210},[185,3184,1004],{"class":206},[185,3186,1007],{"class":220},[185,3188,944],{"class":210},[185,3190,3191,3193,3196,3198,3200,3202,3204],{"class":187,"line":291},[185,3192,977],{"class":210},[185,3194,3195],{"class":206},"memoryCache",[185,3197,983],{"class":210},[185,3199,986],{"class":210},[185,3201,3136],{"class":989},[185,3203,970],{"class":220},[185,3205,944],{"class":210},[185,3207,3208],{"class":187,"line":325},[185,3209,857],{"class":210},[185,3211,3212],{"class":187,"line":331},[185,3213,606],{"class":206},[185,3215,3216],{"class":187,"line":341},[185,3217,3218],{"class":191},"  \u002F\u002F Cache user data\n",[185,3220,3221,3223,3226,3228,3230,3232,3234,3236,3239,3241,3244,3246,3248,3250,3252,3254],{"class":187,"line":361},[185,3222,1049],{"class":202},[185,3224,3225],{"class":220}," cacheUser",[185,3227,992],{"class":210},[185,3229,1058],{"class":1057},[185,3231,224],{"class":210},[185,3233,956],{"class":925},[185,3235,311],{"class":210},[185,3237,3238],{"class":1057}," userData",[185,3240,224],{"class":210},[185,3242,3243],{"class":925}," UserData",[185,3245,1075],{"class":210},[185,3247,1078],{"class":925},[185,3249,1081],{"class":210},[185,3251,2613],{"class":925},[185,3253,1087],{"class":210},[185,3255,214],{"class":210},[185,3257,3258],{"class":187,"line":381},[185,3259,3260],{"class":191},"    \u002F\u002F Memory cache for immediate access\n",[185,3262,3263,3265,3267,3269,3272,3274,3276,3279,3281,3283,3285,3287,3289,3291],{"class":187,"line":400},[185,3264,977],{"class":210},[185,3266,3195],{"class":206},[185,3268,256],{"class":210},[185,3270,3271],{"class":989},"set",[185,3273,992],{"class":220},[185,3275,1461],{"class":210},[185,3277,3278],{"class":305},"user:",[185,3280,1201],{"class":210},[185,3282,1058],{"class":206},[185,3284,1207],{"class":210},[185,3286,311],{"class":210},[185,3288,3238],{"class":206},[185,3290,1007],{"class":220},[185,3292,944],{"class":210},[185,3294,3295],{"class":187,"line":405},[185,3296,481],{"class":220},[185,3298,3299],{"class":187,"line":415},[185,3300,3301],{"class":191},"    \u002F\u002F Redis cache for persistence\n",[185,3303,3304,3306,3308,3310,3312,3314],{"class":187,"line":435},[185,3305,1178],{"class":198},[185,3307,1123],{"class":210},[185,3309,980],{"class":206},[185,3311,256],{"class":210},[185,3313,1187],{"class":989},[185,3315,1190],{"class":220},[185,3317,3318,3320,3322,3324,3326,3328],{"class":187,"line":455},[185,3319,1195],{"class":210},[185,3321,3278],{"class":305},[185,3323,1201],{"class":210},[185,3325,1058],{"class":206},[185,3327,1207],{"class":210},[185,3329,267],{"class":210},[185,3331,3332,3335,3337],{"class":187,"line":473},[185,3333,3334],{"class":544},"      300",[185,3336,311],{"class":210},[185,3338,2680],{"class":191},[185,3340,3341,3343,3345,3347,3349,3352],{"class":187,"line":478},[185,3342,1235],{"class":206},[185,3344,256],{"class":210},[185,3346,1240],{"class":989},[185,3348,992],{"class":220},[185,3350,3351],{"class":206},"userData",[185,3353,1302],{"class":220},[185,3355,3356,3358],{"class":187,"line":484},[185,3357,1307],{"class":220},[185,3359,944],{"class":210},[185,3361,3362],{"class":187,"line":490},[185,3363,857],{"class":210},[185,3365,3366],{"class":187,"line":500},[185,3367,606],{"class":206},[185,3369,3370],{"class":187,"line":514},[185,3371,3372],{"class":191},"  \u002F\u002F Get cached user data\n",[185,3374,3375,3377,3380,3382,3384,3386,3388,3390,3392,3394,3397,3400,3403,3405],{"class":187,"line":526},[185,3376,1049],{"class":202},[185,3378,3379],{"class":220}," getCachedUser",[185,3381,992],{"class":210},[185,3383,1058],{"class":1057},[185,3385,224],{"class":210},[185,3387,956],{"class":925},[185,3389,1075],{"class":210},[185,3391,1078],{"class":925},[185,3393,1081],{"class":210},[185,3395,3396],{"class":925},"UserData",[185,3398,3399],{"class":210}," |",[185,3401,3402],{"class":925}," null",[185,3404,1087],{"class":210},[185,3406,214],{"class":210},[185,3408,3409],{"class":187,"line":536},[185,3410,3411],{"class":191},"    \u002F\u002F Check memory cache first\n",[185,3413,3414,3416,3419,3421,3423,3425,3427,3429,3431,3433,3435,3437,3439,3441,3443],{"class":187,"line":550},[185,3415,1094],{"class":202},[185,3417,3418],{"class":206}," memoryCached",[185,3420,983],{"class":210},[185,3422,1123],{"class":210},[185,3424,3195],{"class":206},[185,3426,256],{"class":210},[185,3428,1456],{"class":989},[185,3430,992],{"class":220},[185,3432,1461],{"class":210},[185,3434,3278],{"class":305},[185,3436,1201],{"class":210},[185,3438,1058],{"class":206},[185,3440,1207],{"class":210},[185,3442,1007],{"class":220},[185,3444,944],{"class":210},[185,3446,3447,3449,3451,3454,3456],{"class":187,"line":562},[185,3448,1478],{"class":198},[185,3450,1363],{"class":220},[185,3452,3453],{"class":206},"memoryCached",[185,3455,1486],{"class":220},[185,3457,1245],{"class":210},[185,3459,3460,3462,3464],{"class":187,"line":574},[185,3461,1626],{"class":198},[185,3463,3418],{"class":206},[185,3465,944],{"class":210},[185,3467,3468],{"class":187,"line":585},[185,3469,594],{"class":210},[185,3471,3472],{"class":187,"line":591},[185,3473,481],{"class":220},[185,3475,3476],{"class":187,"line":597},[185,3477,3478],{"class":191},"    \u002F\u002F Check Redis cache\n",[185,3480,3481,3483,3486,3488,3490,3492,3494,3496,3498,3500,3502,3504,3506,3508,3510,3512],{"class":187,"line":603},[185,3482,1094],{"class":202},[185,3484,3485],{"class":206}," redisCached",[185,3487,983],{"class":210},[185,3489,1447],{"class":198},[185,3491,1123],{"class":210},[185,3493,980],{"class":206},[185,3495,256],{"class":210},[185,3497,1456],{"class":989},[185,3499,992],{"class":220},[185,3501,1461],{"class":210},[185,3503,3278],{"class":305},[185,3505,1201],{"class":210},[185,3507,1058],{"class":206},[185,3509,1207],{"class":210},[185,3511,1007],{"class":220},[185,3513,944],{"class":210},[185,3515,3516,3518,3520,3523,3525],{"class":187,"line":609},[185,3517,1478],{"class":198},[185,3519,1363],{"class":220},[185,3521,3522],{"class":206},"redisCached",[185,3524,1486],{"class":220},[185,3526,1245],{"class":210},[185,3528,3529,3531,3533,3535,3537,3539,3541,3543,3545,3547],{"class":187,"line":615},[185,3530,1493],{"class":202},[185,3532,3238],{"class":206},[185,3534,983],{"class":210},[185,3536,1501],{"class":206},[185,3538,256],{"class":210},[185,3540,1506],{"class":989},[185,3542,992],{"class":220},[185,3544,3522],{"class":206},[185,3546,1007],{"class":220},[185,3548,944],{"class":210},[185,3550,3551],{"class":187,"line":625},[185,3552,3553],{"class":191},"      \u002F\u002F Store in memory cache for next access\n",[185,3555,3556,3559,3561,3563,3565,3567,3569,3571,3573,3575,3577,3579,3581,3583],{"class":187,"line":635},[185,3557,3558],{"class":210},"      this.",[185,3560,3195],{"class":206},[185,3562,256],{"class":210},[185,3564,3271],{"class":989},[185,3566,992],{"class":220},[185,3568,1461],{"class":210},[185,3570,3278],{"class":305},[185,3572,1201],{"class":210},[185,3574,1058],{"class":206},[185,3576,1207],{"class":210},[185,3578,311],{"class":210},[185,3580,3238],{"class":206},[185,3582,1007],{"class":220},[185,3584,944],{"class":210},[185,3586,3587,3589,3591],{"class":187,"line":646},[185,3588,1626],{"class":198},[185,3590,3238],{"class":206},[185,3592,944],{"class":210},[185,3594,3595],{"class":187,"line":682},[185,3596,594],{"class":210},[185,3598,3599],{"class":187,"line":687},[185,3600,481],{"class":220},[185,3602,3603,3605],{"class":187,"line":697},[185,3604,1318],{"class":198},[185,3606,3607],{"class":210}," null;\n",[185,3609,3610],{"class":187,"line":733},[185,3611,857],{"class":210},[185,3613,3614],{"class":187,"line":765},[185,3615,606],{"class":206},[185,3617,3618],{"class":187,"line":776},[185,3619,3620],{"class":191},"  \u002F\u002F Cache session validation\n",[185,3622,3623,3625,3628,3630,3632,3634,3636,3638,3641,3643,3646,3648,3650,3652,3654,3656],{"class":187,"line":781},[185,3624,1049],{"class":202},[185,3626,3627],{"class":220}," cacheSessionValidation",[185,3629,992],{"class":210},[185,3631,1204],{"class":1057},[185,3633,224],{"class":210},[185,3635,956],{"class":925},[185,3637,311],{"class":210},[185,3639,3640],{"class":1057}," validation",[185,3642,224],{"class":210},[185,3644,3645],{"class":925}," SessionValidation",[185,3647,1075],{"class":210},[185,3649,1078],{"class":925},[185,3651,1081],{"class":210},[185,3653,2613],{"class":925},[185,3655,1087],{"class":210},[185,3657,214],{"class":210},[185,3659,3660,3662,3664,3666,3668,3670],{"class":187,"line":791},[185,3661,1178],{"class":198},[185,3663,1123],{"class":210},[185,3665,980],{"class":206},[185,3667,256],{"class":210},[185,3669,1187],{"class":989},[185,3671,1190],{"class":220},[185,3673,3674,3676,3679,3681,3683,3685],{"class":187,"line":804},[185,3675,1195],{"class":210},[185,3677,3678],{"class":305},"session_validation:",[185,3680,1201],{"class":210},[185,3682,1204],{"class":206},[185,3684,1207],{"class":210},[185,3686,267],{"class":210},[185,3688,3689,3692,3694],{"class":187,"line":828},[185,3690,3691],{"class":544},"      60",[185,3693,311],{"class":210},[185,3695,3696],{"class":191}," \u002F\u002F 1 minute\n",[185,3698,3699,3701,3703,3705,3707,3710],{"class":187,"line":849},[185,3700,1235],{"class":206},[185,3702,256],{"class":210},[185,3704,1240],{"class":989},[185,3706,992],{"class":220},[185,3708,3709],{"class":206},"validation",[185,3711,1302],{"class":220},[185,3713,3714,3716],{"class":187,"line":854},[185,3715,1307],{"class":220},[185,3717,944],{"class":210},[185,3719,3720],{"class":187,"line":860},[185,3721,857],{"class":210},[185,3723,3724],{"class":187,"line":1623},[185,3725,2088],{"class":210},[24,3727,3728,3731,3732,256],{},[30,3729,3730],{},"Cross-Link to Caching:","\nFor detailed caching strategies, see our ",[3081,3733,3735],{"href":3734},"\u002Fblog\u002Frijmwoordenboek-caching-optimization","Caching Optimization Guide",[19,3737,3739],{"id":3738},"real-world-results","Real-World Results",[120,3741,3743],{"id":3742},"project-case-study-multi-tenant-saas-platform","Project Case Study: Multi-Tenant SaaS Platform",[24,3745,3746,3749,3750,3753],{},[30,3747,3748],{},"Client",": B2B SaaS platform with 10,000+ users\n",[30,3751,3752],{},"Requirements",": Secure authentication, SSO, compliance",[24,3755,3756],{},[30,3757,3758],{},"Our Solution:",[34,3760,3761,3767,3773,3779,3784],{},[37,3762,3763,3766],{},[30,3764,3765],{},"Authentication Time",": 50ms average (vs 3-5 seconds before)",[37,3768,3769,3772],{},[30,3770,3771],{},"Security Score",": 95\u002F100 (vs 60\u002F100 before)",[37,3774,3775,3778],{},[30,3776,3777],{},"User Adoption",": 90% within 2 weeks",[37,3780,3781,3783],{},[30,3782,96],{},": Reduced by 80%",[37,3785,3786,3788],{},[30,3787,65],{},": SOC2 Type II certified",[24,3790,3791],{},[30,3792,3793],{},"Technical Implementation:",[175,3795,3797],{"className":177,"code":3796,"language":179,"meta":180,"style":180},"\u002F\u002F Production authentication flow\nexport const authFlow = {\n  \u002F\u002F Login with multiple providers\n  async login(provider: string, credentials: any): Promise\u003CAuthResult> {\n    const startTime = Date.now();\n    \n    try {\n      \u002F\u002F Validate credentials\n      const user = await this.validateCredentials(provider, credentials);\n      \n      \u002F\u002F Check 2FA requirement\n      if (user.twoFactorEnabled) {\n        return {\n          requires2FA: true,\n          userId: user.id,\n          methods: user.twoFactorMethods\n        };\n      }\n      \n      \u002F\u002F Create session\n      const session = await this.createSession(user.id, credentials.deviceInfo);\n      \n      \u002F\u002F Cache user data\n      await this.cacheUser(user.id, user);\n      \n      const duration = Date.now() - startTime;\n      console.log(`Login completed in ${duration}ms`);\n      \n      return {\n        success: true,\n        session,\n        user: this.sanitizeUser(user)\n      };\n      \n    } catch (error) {\n      const duration = Date.now() - startTime;\n      console.log(`Login failed in ${duration}ms: ${error.message}`);\n      throw error;\n    }\n  }\n};\n",[182,3798,3799,3804,3817,3822,3860,3879,3883,3890,3895,3923,3928,3933,3952,3959,3970,3986,4000,4005,4009,4013,4018,4054,4058,4063,4088,4092,4116,4150,4154,4160,4171,4178,4196,4201,4205,4221,4243,4282,4291,4295,4299],{"__ignoreMap":180},[185,3800,3801],{"class":187,"line":188},[185,3802,3803],{"class":191},"\u002F\u002F Production authentication flow\n",[185,3805,3806,3808,3810,3813,3815],{"class":187,"line":195},[185,3807,199],{"class":198},[185,3809,203],{"class":202},[185,3811,3812],{"class":206}," authFlow ",[185,3814,211],{"class":210},[185,3816,214],{"class":210},[185,3818,3819],{"class":187,"line":217},[185,3820,3821],{"class":191},"  \u002F\u002F Login with multiple providers\n",[185,3823,3824,3826,3829,3831,3834,3836,3838,3840,3843,3845,3847,3849,3851,3853,3856,3858],{"class":187,"line":229},[185,3825,1049],{"class":202},[185,3827,3828],{"class":220}," login",[185,3830,992],{"class":210},[185,3832,3833],{"class":1057},"provider",[185,3835,224],{"class":210},[185,3837,956],{"class":925},[185,3839,311],{"class":210},[185,3841,3842],{"class":1057}," credentials",[185,3844,224],{"class":210},[185,3846,3145],{"class":925},[185,3848,1075],{"class":210},[185,3850,1078],{"class":925},[185,3852,1081],{"class":210},[185,3854,3855],{"class":925},"AuthResult",[185,3857,1087],{"class":210},[185,3859,214],{"class":210},[185,3861,3862,3864,3867,3869,3871,3873,3875,3877],{"class":187,"line":235},[185,3863,1094],{"class":202},[185,3865,3866],{"class":206}," startTime",[185,3868,983],{"class":210},[185,3870,1269],{"class":206},[185,3872,256],{"class":210},[185,3874,1274],{"class":989},[185,3876,970],{"class":220},[185,3878,944],{"class":210},[185,3880,3881],{"class":187,"line":245},[185,3882,481],{"class":220},[185,3884,3885,3888],{"class":187,"line":270},[185,3886,3887],{"class":198},"    try",[185,3889,214],{"class":210},[185,3891,3892],{"class":187,"line":291},[185,3893,3894],{"class":191},"      \u002F\u002F Validate credentials\n",[185,3896,3897,3899,3902,3904,3906,3908,3911,3913,3915,3917,3919,3921],{"class":187,"line":325},[185,3898,1493],{"class":202},[185,3900,3901],{"class":206}," user",[185,3903,983],{"class":210},[185,3905,1447],{"class":198},[185,3907,1123],{"class":210},[185,3909,3910],{"class":989},"validateCredentials",[185,3912,992],{"class":220},[185,3914,3833],{"class":206},[185,3916,311],{"class":210},[185,3918,3842],{"class":206},[185,3920,1007],{"class":220},[185,3922,944],{"class":210},[185,3924,3925],{"class":187,"line":331},[185,3926,3927],{"class":220},"      \n",[185,3929,3930],{"class":187,"line":341},[185,3931,3932],{"class":191},"      \u002F\u002F Check 2FA requirement\n",[185,3934,3935,3938,3940,3943,3945,3948,3950],{"class":187,"line":361},[185,3936,3937],{"class":198},"      if",[185,3939,1363],{"class":220},[185,3941,3942],{"class":206},"user",[185,3944,256],{"class":210},[185,3946,3947],{"class":206},"twoFactorEnabled",[185,3949,1486],{"class":220},[185,3951,1245],{"class":210},[185,3953,3954,3957],{"class":187,"line":381},[185,3955,3956],{"class":198},"        return",[185,3958,214],{"class":210},[185,3960,3961,3964,3966,3968],{"class":187,"line":400},[185,3962,3963],{"class":220},"          requires2FA",[185,3965,224],{"class":210},[185,3967,509],{"class":508},[185,3969,267],{"class":210},[185,3971,3972,3975,3977,3979,3981,3984],{"class":187,"line":405},[185,3973,3974],{"class":220},"          userId",[185,3976,224],{"class":210},[185,3978,3901],{"class":206},[185,3980,256],{"class":210},[185,3982,3983],{"class":206},"id",[185,3985,267],{"class":210},[185,3987,3988,3991,3993,3995,3997],{"class":187,"line":415},[185,3989,3990],{"class":220},"          methods",[185,3992,224],{"class":210},[185,3994,3901],{"class":206},[185,3996,256],{"class":210},[185,3998,3999],{"class":206},"twoFactorMethods\n",[185,4001,4002],{"class":187,"line":435},[185,4003,4004],{"class":210},"        };\n",[185,4006,4007],{"class":187,"line":455},[185,4008,588],{"class":210},[185,4010,4011],{"class":187,"line":473},[185,4012,3927],{"class":220},[185,4014,4015],{"class":187,"line":478},[185,4016,4017],{"class":191},"      \u002F\u002F Create session\n",[185,4019,4020,4022,4024,4026,4028,4030,4033,4035,4037,4039,4041,4043,4045,4047,4050,4052],{"class":187,"line":484},[185,4021,1493],{"class":202},[185,4023,1496],{"class":206},[185,4025,983],{"class":210},[185,4027,1447],{"class":198},[185,4029,1123],{"class":210},[185,4031,4032],{"class":989},"createSession",[185,4034,992],{"class":220},[185,4036,3942],{"class":206},[185,4038,256],{"class":210},[185,4040,3983],{"class":206},[185,4042,311],{"class":210},[185,4044,3842],{"class":206},[185,4046,256],{"class":210},[185,4048,4049],{"class":206},"deviceInfo",[185,4051,1007],{"class":220},[185,4053,944],{"class":210},[185,4055,4056],{"class":187,"line":490},[185,4057,3927],{"class":220},[185,4059,4060],{"class":187,"line":500},[185,4061,4062],{"class":191},"      \u002F\u002F Cache user data\n",[185,4064,4065,4067,4069,4072,4074,4076,4078,4080,4082,4084,4086],{"class":187,"line":514},[185,4066,1524],{"class":198},[185,4068,1123],{"class":210},[185,4070,4071],{"class":989},"cacheUser",[185,4073,992],{"class":220},[185,4075,3942],{"class":206},[185,4077,256],{"class":210},[185,4079,3983],{"class":206},[185,4081,311],{"class":210},[185,4083,3901],{"class":206},[185,4085,1007],{"class":220},[185,4087,944],{"class":210},[185,4089,4090],{"class":187,"line":526},[185,4091,3927],{"class":220},[185,4093,4094,4096,4099,4101,4103,4105,4107,4109,4112,4114],{"class":187,"line":536},[185,4095,1493],{"class":202},[185,4097,4098],{"class":206}," duration",[185,4100,983],{"class":210},[185,4102,1269],{"class":206},[185,4104,256],{"class":210},[185,4106,1274],{"class":989},[185,4108,1357],{"class":220},[185,4110,4111],{"class":210},"-",[185,4113,3866],{"class":206},[185,4115,944],{"class":210},[185,4117,4118,4121,4123,4126,4128,4130,4133,4135,4138,4141,4144,4146,4148],{"class":187,"line":550},[185,4119,4120],{"class":206},"      console",[185,4122,256],{"class":210},[185,4124,4125],{"class":989},"log",[185,4127,992],{"class":220},[185,4129,1461],{"class":210},[185,4131,4132],{"class":305},"Login completed in ",[185,4134,1201],{"class":210},[185,4136,4137],{"class":206},"duration",[185,4139,4140],{"class":210},"}",[185,4142,4143],{"class":305},"ms",[185,4145,1461],{"class":210},[185,4147,1007],{"class":220},[185,4149,944],{"class":210},[185,4151,4152],{"class":187,"line":562},[185,4153,3927],{"class":220},[185,4155,4156,4158],{"class":187,"line":574},[185,4157,1626],{"class":198},[185,4159,214],{"class":210},[185,4161,4162,4165,4167,4169],{"class":187,"line":585},[185,4163,4164],{"class":220},"        success",[185,4166,224],{"class":210},[185,4168,509],{"class":508},[185,4170,267],{"class":210},[185,4172,4173,4176],{"class":187,"line":591},[185,4174,4175],{"class":206},"        session",[185,4177,267],{"class":210},[185,4179,4180,4183,4185,4187,4190,4192,4194],{"class":187,"line":597},[185,4181,4182],{"class":220},"        user",[185,4184,224],{"class":210},[185,4186,1123],{"class":210},[185,4188,4189],{"class":989},"sanitizeUser",[185,4191,992],{"class":220},[185,4193,3942],{"class":206},[185,4195,1302],{"class":220},[185,4197,4198],{"class":187,"line":603},[185,4199,4200],{"class":210},"      };\n",[185,4202,4203],{"class":187,"line":609},[185,4204,3927],{"class":220},[185,4206,4207,4209,4212,4214,4217,4219],{"class":187,"line":615},[185,4208,2516],{"class":210},[185,4210,4211],{"class":198}," catch",[185,4213,1363],{"class":220},[185,4215,4216],{"class":206},"error",[185,4218,1486],{"class":220},[185,4220,1245],{"class":210},[185,4222,4223,4225,4227,4229,4231,4233,4235,4237,4239,4241],{"class":187,"line":625},[185,4224,1493],{"class":202},[185,4226,4098],{"class":206},[185,4228,983],{"class":210},[185,4230,1269],{"class":206},[185,4232,256],{"class":210},[185,4234,1274],{"class":989},[185,4236,1357],{"class":220},[185,4238,4111],{"class":210},[185,4240,3866],{"class":206},[185,4242,944],{"class":210},[185,4244,4245,4247,4249,4251,4253,4255,4258,4260,4262,4264,4267,4269,4271,4273,4276,4278,4280],{"class":187,"line":635},[185,4246,4120],{"class":206},[185,4248,256],{"class":210},[185,4250,4125],{"class":989},[185,4252,992],{"class":220},[185,4254,1461],{"class":210},[185,4256,4257],{"class":305},"Login failed in ",[185,4259,1201],{"class":210},[185,4261,4137],{"class":206},[185,4263,4140],{"class":210},[185,4265,4266],{"class":305},"ms: ",[185,4268,1201],{"class":210},[185,4270,4216],{"class":206},[185,4272,256],{"class":210},[185,4274,4275],{"class":206},"message",[185,4277,1207],{"class":210},[185,4279,1007],{"class":220},[185,4281,944],{"class":210},[185,4283,4284,4286,4289],{"class":187,"line":646},[185,4285,1781],{"class":198},[185,4287,4288],{"class":206}," error",[185,4290,944],{"class":210},[185,4292,4293],{"class":187,"line":682},[185,4294,594],{"class":210},[185,4296,4297],{"class":187,"line":687},[185,4298,857],{"class":210},[185,4300,4301],{"class":187,"line":697},[185,4302,863],{"class":210},[19,4304,150],{"id":4305},"security-best-practices",[120,4307,4309],{"id":4308},"_1-password-security","1. Password Security",[34,4311,4312,4318,4324,4330],{},[37,4313,4314,4317],{},[30,4315,4316],{},"Strong Policies",": Minimum 8 characters, mixed case, numbers, special characters",[37,4319,4320,4323],{},[30,4321,4322],{},"Hashing",": bcrypt with salt rounds ≥ 12",[37,4325,4326,4329],{},[30,4327,4328],{},"Breach Detection",": Check against known password breaches",[37,4331,4332,4334],{},[30,4333,2954],{},": Prevent brute force attacks",[120,4336,4338],{"id":4337},"_2-session-security","2. Session Security",[34,4340,4341,4347,4352,4357],{},[37,4342,4343,4346],{},[30,4344,4345],{},"Secure Cookies",": HttpOnly, Secure, SameSite attributes",[37,4348,4349,4351],{},[30,4350,2105],{},": Regular refresh token rotation",[37,4353,4354,4356],{},[30,4355,2111],{},": Monitor and manage device sessions",[37,4358,4359,4362],{},[30,4360,4361],{},"Automatic Logout",": Inactive session timeout",[120,4364,4366],{"id":4365},"_3-oauth2-security","3. OAuth2 Security",[34,4368,4369,4375,4381,4387],{},[37,4370,4371,4374],{},[30,4372,4373],{},"State Parameter",": Prevent CSRF attacks",[37,4376,4377,4380],{},[30,4378,4379],{},"PKCE",": Proof Key for Code Exchange for public clients",[37,4382,4383,4386],{},[30,4384,4385],{},"Scope Validation",": Limit access to required permissions only",[37,4388,4389,4392],{},[30,4390,4391],{},"Token Validation",": Verify JWT signatures and claims",[19,4394,4396],{"id":4395},"implementation-checklist","Implementation Checklist",[24,4398,4399],{},"If you're implementing authentication strategies:",[34,4401,4404,4417,4426,4435,4444,4453,4462],{"className":4402},[4403],"contains-task-list",[37,4405,4408,4412,4413,4416],{"className":4406},[4407],"task-list-item",[4409,4410],"input",{"disabled":3009,"type":4411},"checkbox"," ",[30,4414,4415],{},"Choose authentication providers",": OAuth2, email\u002Fpassword, or both",[37,4418,4420,4412,4422,4425],{"className":4419},[4407],[4409,4421],{"disabled":3009,"type":4411},[30,4423,4424],{},"Implement security measures",": 2FA, rate limiting, secure storage",[37,4427,4429,4412,4431,4434],{"className":4428},[4407],[4409,4430],{"disabled":3009,"type":4411},[30,4432,4433],{},"Optimize performance",": Database queries, caching, session management",[37,4436,4438,4412,4440,4443],{"className":4437},[4407],[4409,4439],{"disabled":3009,"type":4411},[30,4441,4442],{},"Ensure compliance",": GDPR, SOC2, industry-specific requirements",[37,4445,4447,4412,4449,4452],{"className":4446},[4407],[4409,4448],{"disabled":3009,"type":4411},[30,4450,4451],{},"Test thoroughly",": Security testing, performance testing, user testing",[37,4454,4456,4412,4458,4461],{"className":4455},[4407],[4409,4457],{"disabled":3009,"type":4411},[30,4459,4460],{},"Monitor and audit",": Log authentication events, track security metrics",[37,4463,4465,4412,4467,4470],{"className":4464},[4407],[4409,4466],{"disabled":3009,"type":4411},[30,4468,4469],{},"Plan for scale",": Handle increasing user loads and concurrent sessions",[19,4472,4474],{"id":4473},"cross-linked-resources","Cross-Linked Resources",[24,4476,4477],{},"Authentication strategies often intersect with other development areas:",[34,4479,4480,4488,4496,4505],{},[37,4481,4482,4487],{},[30,4483,4484],{},[3081,4485,4486],{"href":3083},"PostgreSQL Performance Tuning",": Database optimization for auth",[37,4489,4490,4495],{},[30,4491,4492],{},[3081,4493,4494],{"href":3734},"Caching Optimization",": Fast session validation",[37,4497,4498,4504],{},[30,4499,4500],{},[3081,4501,4503],{"href":4502},"\u002Fblog\u002Fcustomer-portal-development","Customer Portal Development",": Auth in portal applications",[37,4506,4507,4513],{},[30,4508,4509],{},[3081,4510,4512],{"href":4511},"\u002Fblog\u002Fsaas-architecture-patterns","SaaS Architecture Patterns",": Multi-tenant authentication",[19,4515,4517],{"id":4516},"summary","Summary",[24,4519,4520],{},"Modern authentication doesn't have to be a choice between security and performance. By implementing comprehensive authentication strategies with proper security measures, performance optimization, and user experience focus, we've achieved both security and speed.",[24,4522,4523],{},"The key is treating authentication as a system-wide concern that requires careful planning, implementation, and ongoing monitoring.",[24,4525,4526],{},"If this article helped you understand authentication strategies, we can help you implement secure, fast authentication in your applications. At Ludulicious, we specialize in:",[34,4528,4529,4535,4540,4545],{},[37,4530,4531,4534],{},[30,4532,4533],{},"Authentication Systems",": Secure, modern authentication solutions",[37,4536,4537,151],{},[30,4538,4539],{},"Security Implementation",[37,4541,4542,4544],{},[30,4543,144],{},": Fast authentication operations",[37,4546,4547,66],{},[30,4548,65],{},[24,4550,4551],{},[30,4552,4553],{},"Ready to implement secure, fast authentication?",[24,4555,4556,4560],{},[3081,4557,4559],{"href":4558},"\u002Fcontact","Contact us"," for a free consultation, or check out our other development guides:",[34,4562,4563,4568,4573,4578],{},[37,4564,4565],{},[3081,4566,4567],{"href":3083},"PostgreSQL Performance Tuning: Strategic Lessons from Production",[37,4569,4570],{},[3081,4571,4572],{"href":4502},"Customer Portal Development: From 6 Months to 6 Weeks",[37,4574,4575],{},[3081,4576,4577],{"href":3734},"Caching Optimization: Sub-15ms Response Times",[37,4579,4580],{},[3081,4581,4582],{"href":4511},"SaaS Architecture Patterns: Building Scalable Applications",[4584,4585],"hr",{},[24,4587,4588],{},[4589,4590,4591],"em",{},"This authentication strategies guide is based on real production experience implementing secure authentication systems. All performance numbers and security metrics are from actual production applications.",[4593,4594,4595],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":180,"searchDepth":195,"depth":195,"links":4597},[4598,4599,4602,4607,4611,4614,4619,4620,4621],{"id":21,"depth":195,"text":22},{"id":117,"depth":195,"text":118,"children":4600},[4601],{"id":122,"depth":217,"text":123},{"id":165,"depth":195,"text":166,"children":4603},[4604,4605,4606],{"id":169,"depth":217,"text":170},{"id":901,"depth":217,"text":902},{"id":2126,"depth":217,"text":2127},{"id":2969,"depth":195,"text":2970,"children":4608},[4609,4610],{"id":2973,"depth":217,"text":2974},{"id":3087,"depth":217,"text":3088},{"id":3738,"depth":195,"text":3739,"children":4612},[4613],{"id":3742,"depth":217,"text":3743},{"id":4305,"depth":195,"text":150,"children":4615},[4616,4617,4618],{"id":4308,"depth":217,"text":4309},{"id":4337,"depth":217,"text":4338},{"id":4365,"depth":217,"text":4366},{"id":4395,"depth":195,"text":4396},{"id":4473,"depth":195,"text":4474},{"id":4516,"depth":195,"text":4517},[14,4623],"Authentication","2025-01-17","Learn modern authentication strategies for web applications, from OAuth2 flows to session management. Real-world implementation patterns that ensure security while maintaining optimal performance and user experience.","md",{"src":4628},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F16\u002F640\u002F360",{"schema":4630},{"type":4631,"name":5,"description":4625,"image":4628,"author":4632,"datePublished":4624,"dateModified":4624,"publisher":4633,"steps":4636,"totalTime":4655,"estimatedCost":4656},"HowTo",{"name":8,"url":9},{"name":4634,"url":4635},"Ludulicious B.V.","https:\u002F\u002Fludulicious.nl",[4637,4640,4643,4646,4649,4652],{"name":4638,"text":4639},"Choose Authentication Providers","Select OAuth2 providers and email\u002Fpassword authentication methods",{"name":4641,"text":4642},"Implement Multi-Provider Support","Set up unified authentication supporting multiple providers",{"name":4644,"text":4645},"Configure Session Management","Implement secure session management with Redis caching",{"name":4647,"text":4648},"Add Two-Factor Authentication","Implement 2FA with TOTP, SMS, and email options",{"name":4650,"text":4651},"Optimize Performance","Configure caching and database optimization for fast authentication",{"name":4653,"text":4654},"Implement Security Measures","Add rate limiting, password policies, and security monitoring","PT5D",{"currency":4657,"value":4658},"EUR","10000","\u002Fblog\u002Fauthentication-strategies",{"title":5,"description":4625},"blog\u002F12.authentication-strategies",[4623,14,4663,53,4664,4665,4666],"OAuth2","User Management","JWT","Performance","qPk9sC8yU_mfRmknqcpnnBXA1m41x4XIs1b5W1TLoy8",[4669,4674],{"title":4670,"path":4671,"stem":4672,"description":4673,"children":-1},"Domain Structure Challenges: When Clients Don't Know What They Want","\u002Fblog\u002Fdomain-structure-challenges","blog\u002F11.domain-structure-challenges","Learn how to navigate domain structure challenges when clients are uncertain about their requirements. Real-world strategies for gathering requirements, managing scope creep, and delivering successful projects despite unclear initial specifications.",{"title":4582,"path":4511,"stem":4675,"description":4676,"children":-1},"blog\u002F13.saas-architecture-patterns","Learn proven SaaS architecture patterns for building scalable, multi-tenant applications. Real-world strategies for database design, API architecture, and deployment that handle growth from startup to enterprise scale.",[]]