[{"data":1,"prerenderedAt":913},["ShallowReactive",2],{"navigation":3,"\u002Fcomposables\u002Frecipes":94,"\u002Fcomposables\u002Frecipes-surround":908},[4,33,52],{"title":5,"path":6,"stem":7,"children":8,"icon":32},"Getting Started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,12,17,22,27],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-play",{"title":23,"path":24,"stem":25,"icon":26},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F4.configuration","i-lucide-settings",{"title":28,"path":29,"stem":30,"icon":31},"Production","\u002Fgetting-started\u002Fproduction","1.getting-started\u002F5.production","i-lucide-shield-check","i-lucide-rocket",{"title":34,"path":35,"stem":36,"children":37,"icon":51},"Composable Endpoints","\u002Fcomposables","2.composables\u002F1.index",[38,41,46],{"title":39,"path":35,"stem":36,"icon":40},"Overview","i-lucide-layout-grid",{"title":42,"path":43,"stem":44,"icon":45},"Requirements","\u002Fcomposables\u002Frequirements","2.composables\u002F2.requirements","i-lucide-list-checks",{"title":47,"path":48,"stem":49,"icon":50},"Recipes","\u002Fcomposables\u002Frecipes","2.composables\u002F3.recipes","i-lucide-book-marked","i-lucide-blocks",{"title":53,"icon":54,"path":55,"stem":56,"children":57,"page":93},"Modules","i-lucide-package","\u002Fmodules","3.modules",[58,63,68,73,78,83,88],{"title":59,"path":60,"stem":61,"icon":62},"Identity management","\u002Fmodules\u002Fidentity-management","3.modules\u002F1.identity-management","i-lucide-user-cog",{"title":64,"path":65,"stem":66,"icon":67},"Cookie auth","\u002Fmodules\u002Fcookie-auth","3.modules\u002F2.cookie-auth","i-lucide-cookie",{"title":69,"path":70,"stem":71,"icon":72},"Bearer auth","\u002Fmodules\u002Fbearer-auth","3.modules\u002F3.bearer-auth","i-lucide-key",{"title":74,"path":75,"stem":76,"icon":77},"JWT","\u002Fmodules\u002Fjwt","3.modules\u002F4.jwt","i-lucide-fingerprint",{"title":79,"path":80,"stem":81,"icon":82},"Passkeys","\u002Fmodules\u002Fpasskeys","3.modules\u002F5.passkeys","i-lucide-scan-face",{"title":84,"path":85,"stem":86,"icon":87},"ReAuth","\u002Fmodules\u002Freauth","3.modules\u002F6.reauth","i-lucide-shield-alert",{"title":89,"path":90,"stem":91,"icon":92},"External OAuth","\u002Fmodules\u002Fexternal-oauth","3.modules\u002F7.external-oauth","i-lucide-log-in",false,{"id":95,"title":47,"body":96,"description":901,"extension":902,"links":903,"meta":904,"navigation":905,"path":48,"seo":906,"stem":49,"__hash__":907},"docs\u002F2.composables\u002F3.recipes.md",{"type":97,"value":98,"toc":892},"minimark",[99,104,198,202,211,758,762,765,782,785,788,804,807,810,844,847,862,866,888],[100,101,103],"h2",{"id":102},"recipe-matrix","Recipe matrix",[105,106,107,125],"table",{},[108,109,110],"thead",{},[111,112,113,117,120,123],"tr",{},[114,115,116],"th",{},"Recipe",[114,118,119],{},"Management group",[114,121,122],{},"Sign-in group",[114,124,79],{},[126,127,128,150,167,185],"tbody",{},[111,129,130,134,140,145],{},[131,132,133],"td",{},"Cookie SPA (default facade)",[131,135,136],{},[137,138,139],"code",{},"\u002Fidentity",[131,141,142,143],{},"cookie ",[137,144,139],{},[131,146,147],{},[137,148,149],{},"\u002Faccount",[111,151,152,155,159,164],{},[131,153,154],{},"Identity bearer",[131,156,157],{},[137,158,139],{},[131,160,161,162],{},"bearer ",[137,163,139],{},[131,165,166],{},"optional",[111,168,169,172,177,183],{},[131,170,171],{},"JWT-only",[131,173,174,175],{},"e.g. ",[137,176,149],{},[131,178,179,180],{},"JWT ",[137,181,182],{},"\u002Fauth",[131,184,166],{},[111,186,187,190,193,196],{},[131,188,189],{},"Custom paths",[131,191,192],{},"any prefix",[131,194,195],{},"matching DI",[131,197,192],{},[100,199,201],{"id":200},"advanced-composition","Advanced composition",[203,204,205,206,210],"p",{},"Compose modules yourself when you need bearer Identity, custom paths, or JWT-only. Map management ",[207,208,209],"strong",{},"once"," in production hosts.",[212,213,218],"pre",{"className":214,"code":215,"language":216,"meta":217,"style":217},"language-cs shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","builder.Services\n    .AddIdentityApiEndpoints\u003CAppUser>(o =>\n    {\n        o.Stores.SchemaVersion = IdentitySchemaVersions.Version3;\n    })\n    .AddEntityFrameworkStores\u003CAppDbContext>()\n    .AddDefaultTokenProviders();\n\nbuilder.Services.AddAntiforgery();\nbuilder.Services.AddCookieAuthEndpoints(); \u002F\u002F rate limits + ReAuth schemes\nbuilder.Services.AddPasskeyEndpoints();\nbuilder.Services.AddJwtEndpoints\u003CAppUser, AppDbContext>(o =>\n{\n    o.Issuer = \"https:\u002F\u002Fexample.com\";\n    o.Audience = \"https:\u002F\u002Fexample.com\";\n    o.SigningOptions.SymmetricKey = builder.Configuration[\"Jwt:SymmetricKey\"];\n});\n\n\u002F\u002F In AppDbContext.OnModelCreating:\n\u002F\u002F   builder.UseRefreshToken();\n\nvar app = builder.Build();\napp.UseAuthentication();\napp.UseAuthorization();\napp.UseRateLimiter();\napp.UseAntiforgery();\n\n\u002F\u002F Cookie SPA\napp.MapGroup(\"\u002Fidentity\").MapIdentityManagementApi\u003CAppUser>();\napp.MapGroup(\"\u002Fidentity\").MapCookieAuthEndpoints\u003CAppUser>();\n\n\u002F\u002F Or Identity bearer\n\u002F\u002F app.MapGroup(\"\u002Fidentity\").MapIdentityManagementApi\u003CAppUser>();\n\u002F\u002F app.MapGroup(\"\u002Fidentity\").MapBearerAuthEndpoints\u003CAppUser>();\n\n\u002F\u002F Or JWT-only (no cookie login)\n\u002F\u002F app.MapGroup(\"\u002Faccount\").MapIdentityManagementApi\u003CAppUser>();\n\u002F\u002F app.MapGroup(\"\u002Fauth\").MapJwtAuthEndpoints\u003CAppUser>();\n\napp.MapGroup(\"\u002Faccount\").MapPasskeyEndpoints\u003CAppUser>();\n","cs","",[137,219,220,236,262,268,298,304,320,331,338,355,376,392,422,428,453,473,510,516,521,527,533,538,559,572,584,596,608,613,619,651,679,684,690,696,702,707,713,719,725,730],{"__ignoreMap":217},[221,222,225,229,233],"span",{"class":223,"line":224},"line",1,[221,226,228],{"class":227},"sTEyZ","builder",[221,230,232],{"class":231},"sMK4o",".",[221,234,235],{"class":227},"Services\n",[221,237,239,242,246,249,253,256,259],{"class":223,"line":238},2,[221,240,241],{"class":231},"    .",[221,243,245],{"class":244},"s2Zo4","AddIdentityApiEndpoints",[221,247,248],{"class":231},"\u003C",[221,250,252],{"class":251},"sBMFI","AppUser",[221,254,255],{"class":231},">(",[221,257,258],{"class":251},"o",[221,260,261],{"class":231}," =>\n",[221,263,265],{"class":223,"line":264},3,[221,266,267],{"class":231},"    {\n",[221,269,271,274,276,279,281,284,287,290,292,295],{"class":223,"line":270},4,[221,272,273],{"class":227},"        o",[221,275,232],{"class":231},[221,277,278],{"class":227},"Stores",[221,280,232],{"class":231},[221,282,283],{"class":227},"SchemaVersion ",[221,285,286],{"class":231},"=",[221,288,289],{"class":227}," IdentitySchemaVersions",[221,291,232],{"class":231},[221,293,294],{"class":227},"Version3",[221,296,297],{"class":231},";\n",[221,299,301],{"class":223,"line":300},5,[221,302,303],{"class":231},"    })\n",[221,305,307,309,312,314,317],{"class":223,"line":306},6,[221,308,241],{"class":231},[221,310,311],{"class":244},"AddEntityFrameworkStores",[221,313,248],{"class":231},[221,315,316],{"class":251},"AppDbContext",[221,318,319],{"class":231},">()\n",[221,321,323,325,328],{"class":223,"line":322},7,[221,324,241],{"class":231},[221,326,327],{"class":244},"AddDefaultTokenProviders",[221,329,330],{"class":231},"();\n",[221,332,334],{"class":223,"line":333},8,[221,335,337],{"emptyLinePlaceholder":336},true,"\n",[221,339,341,343,345,348,350,353],{"class":223,"line":340},9,[221,342,228],{"class":227},[221,344,232],{"class":231},[221,346,347],{"class":227},"Services",[221,349,232],{"class":231},[221,351,352],{"class":244},"AddAntiforgery",[221,354,330],{"class":231},[221,356,358,360,362,364,366,369,372],{"class":223,"line":357},10,[221,359,228],{"class":227},[221,361,232],{"class":231},[221,363,347],{"class":227},[221,365,232],{"class":231},[221,367,368],{"class":244},"AddCookieAuthEndpoints",[221,370,371],{"class":231},"();",[221,373,375],{"class":374},"sHwdD"," \u002F\u002F rate limits + ReAuth schemes\n",[221,377,379,381,383,385,387,390],{"class":223,"line":378},11,[221,380,228],{"class":227},[221,382,232],{"class":231},[221,384,347],{"class":227},[221,386,232],{"class":231},[221,388,389],{"class":244},"AddPasskeyEndpoints",[221,391,330],{"class":231},[221,393,395,397,399,401,403,406,408,410,413,416,418,420],{"class":223,"line":394},12,[221,396,228],{"class":227},[221,398,232],{"class":231},[221,400,347],{"class":227},[221,402,232],{"class":231},[221,404,405],{"class":244},"AddJwtEndpoints",[221,407,248],{"class":231},[221,409,252],{"class":251},[221,411,412],{"class":231},",",[221,414,415],{"class":251}," AppDbContext",[221,417,255],{"class":231},[221,419,258],{"class":251},[221,421,261],{"class":231},[221,423,425],{"class":223,"line":424},13,[221,426,427],{"class":231},"{\n",[221,429,431,434,436,439,441,444,448,451],{"class":223,"line":430},14,[221,432,433],{"class":227},"    o",[221,435,232],{"class":231},[221,437,438],{"class":227},"Issuer ",[221,440,286],{"class":231},[221,442,443],{"class":231}," \"",[221,445,447],{"class":446},"sfazB","https:\u002F\u002Fexample.com",[221,449,450],{"class":231},"\"",[221,452,297],{"class":231},[221,454,456,458,460,463,465,467,469,471],{"class":223,"line":455},15,[221,457,433],{"class":227},[221,459,232],{"class":231},[221,461,462],{"class":227},"Audience ",[221,464,286],{"class":231},[221,466,443],{"class":231},[221,468,447],{"class":446},[221,470,450],{"class":231},[221,472,297],{"class":231},[221,474,476,478,480,483,485,488,490,493,495,497,500,502,505,507],{"class":223,"line":475},16,[221,477,433],{"class":227},[221,479,232],{"class":231},[221,481,482],{"class":227},"SigningOptions",[221,484,232],{"class":231},[221,486,487],{"class":227},"SymmetricKey ",[221,489,286],{"class":231},[221,491,492],{"class":227}," builder",[221,494,232],{"class":231},[221,496,23],{"class":227},[221,498,499],{"class":231},"[",[221,501,450],{"class":231},[221,503,504],{"class":446},"Jwt:SymmetricKey",[221,506,450],{"class":231},[221,508,509],{"class":231},"];\n",[221,511,513],{"class":223,"line":512},17,[221,514,515],{"class":231},"});\n",[221,517,519],{"class":223,"line":518},18,[221,520,337],{"emptyLinePlaceholder":336},[221,522,524],{"class":223,"line":523},19,[221,525,526],{"class":374},"\u002F\u002F In AppDbContext.OnModelCreating:\n",[221,528,530],{"class":223,"line":529},20,[221,531,532],{"class":374},"\u002F\u002F   builder.UseRefreshToken();\n",[221,534,536],{"class":223,"line":535},21,[221,537,337],{"emptyLinePlaceholder":336},[221,539,541,544,547,550,552,554,557],{"class":223,"line":540},22,[221,542,543],{"class":251},"var",[221,545,546],{"class":251}," app",[221,548,549],{"class":231}," =",[221,551,492],{"class":227},[221,553,232],{"class":231},[221,555,556],{"class":244},"Build",[221,558,330],{"class":231},[221,560,562,565,567,570],{"class":223,"line":561},23,[221,563,564],{"class":227},"app",[221,566,232],{"class":231},[221,568,569],{"class":244},"UseAuthentication",[221,571,330],{"class":231},[221,573,575,577,579,582],{"class":223,"line":574},24,[221,576,564],{"class":227},[221,578,232],{"class":231},[221,580,581],{"class":244},"UseAuthorization",[221,583,330],{"class":231},[221,585,587,589,591,594],{"class":223,"line":586},25,[221,588,564],{"class":227},[221,590,232],{"class":231},[221,592,593],{"class":244},"UseRateLimiter",[221,595,330],{"class":231},[221,597,599,601,603,606],{"class":223,"line":598},26,[221,600,564],{"class":227},[221,602,232],{"class":231},[221,604,605],{"class":244},"UseAntiforgery",[221,607,330],{"class":231},[221,609,611],{"class":223,"line":610},27,[221,612,337],{"emptyLinePlaceholder":336},[221,614,616],{"class":223,"line":615},28,[221,617,618],{"class":374},"\u002F\u002F Cookie SPA\n",[221,620,622,624,626,629,632,634,636,638,641,644,646,648],{"class":223,"line":621},29,[221,623,564],{"class":227},[221,625,232],{"class":231},[221,627,628],{"class":244},"MapGroup",[221,630,631],{"class":231},"(",[221,633,450],{"class":231},[221,635,139],{"class":446},[221,637,450],{"class":231},[221,639,640],{"class":231},").",[221,642,643],{"class":244},"MapIdentityManagementApi",[221,645,248],{"class":231},[221,647,252],{"class":251},[221,649,650],{"class":231},">();\n",[221,652,654,656,658,660,662,664,666,668,670,673,675,677],{"class":223,"line":653},30,[221,655,564],{"class":227},[221,657,232],{"class":231},[221,659,628],{"class":244},[221,661,631],{"class":231},[221,663,450],{"class":231},[221,665,139],{"class":446},[221,667,450],{"class":231},[221,669,640],{"class":231},[221,671,672],{"class":244},"MapCookieAuthEndpoints",[221,674,248],{"class":231},[221,676,252],{"class":251},[221,678,650],{"class":231},[221,680,682],{"class":223,"line":681},31,[221,683,337],{"emptyLinePlaceholder":336},[221,685,687],{"class":223,"line":686},32,[221,688,689],{"class":374},"\u002F\u002F Or Identity bearer\n",[221,691,693],{"class":223,"line":692},33,[221,694,695],{"class":374},"\u002F\u002F app.MapGroup(\"\u002Fidentity\").MapIdentityManagementApi\u003CAppUser>();\n",[221,697,699],{"class":223,"line":698},34,[221,700,701],{"class":374},"\u002F\u002F app.MapGroup(\"\u002Fidentity\").MapBearerAuthEndpoints\u003CAppUser>();\n",[221,703,705],{"class":223,"line":704},35,[221,706,337],{"emptyLinePlaceholder":336},[221,708,710],{"class":223,"line":709},36,[221,711,712],{"class":374},"\u002F\u002F Or JWT-only (no cookie login)\n",[221,714,716],{"class":223,"line":715},37,[221,717,718],{"class":374},"\u002F\u002F app.MapGroup(\"\u002Faccount\").MapIdentityManagementApi\u003CAppUser>();\n",[221,720,722],{"class":223,"line":721},38,[221,723,724],{"class":374},"\u002F\u002F app.MapGroup(\"\u002Fauth\").MapJwtAuthEndpoints\u003CAppUser>();\n",[221,726,728],{"class":223,"line":727},39,[221,729,337],{"emptyLinePlaceholder":336},[221,731,733,735,737,739,741,743,745,747,749,752,754,756],{"class":223,"line":732},40,[221,734,564],{"class":227},[221,736,232],{"class":231},[221,738,628],{"class":244},[221,740,631],{"class":231},[221,742,450],{"class":231},[221,744,149],{"class":446},[221,746,450],{"class":231},[221,748,640],{"class":231},[221,750,751],{"class":244},"MapPasskeyEndpoints",[221,753,248],{"class":231},[221,755,252],{"class":251},[221,757,650],{"class":231},[100,759,761],{"id":760},"cookie-spa","Cookie SPA",[203,763,764],{},"Best default for a first-party SPA on the same site (or carefully configured CORS + credentials).",[766,767,768,774,779],"ul",{},[769,770,771,772],"li",{},"Management + cookie on ",[137,773,139],{},[769,775,776,777],{},"Passkeys on ",[137,778,149],{},[769,780,781],{},"Client uses credentials + CSRF token",[100,783,154],{"id":784},"identity-bearer",[203,786,787],{},"Use when the SPA stores Identity bearer tokens (ASP.NET Core Identity API token format) instead of cookies.",[766,789,790,797],{},[769,791,792,793,796],{},"Map ",[137,794,795],{},"MapBearerAuthEndpoints"," instead of cookie",[769,798,799,800,803],{},"CSRF is skipped for bearer-authenticated unsafe methods (see ",[801,802,42],"a",{"href":43},")",[100,805,171],{"id":806},"jwt-only",[203,808,809],{},"Use JWT for access tokens and an HttpOnly refresh cookie.",[766,811,812,817,826,833],{},[769,813,814,815,803],{},"Management on one prefix (e.g. ",[137,816,149],{},[769,818,819,822,823,825],{},[137,820,821],{},"MapJwtAuthEndpoints"," on ",[137,824,182],{}," (or your choice)",[769,827,828,829,832],{},"Still call ",[137,830,831],{},"UseRefreshToken()"," and migrate",[769,834,835,836,839,840,843],{},"Passkeys do ",[207,837,838],{},"not"," issue JWT — after passkey login, call ",[137,841,842],{},"\u002Fauth\u002Fcreate"," if you need a JWT",[100,845,189],{"id":846},"custom-paths",[203,848,849,850,853,854,857,858,861],{},"Prefixes are arbitrary as long as DI and middleware match. The Demo host uses paths such as ",[137,851,852],{},"\u002Fauth\u002Fcookie",", ",[137,855,856],{},"\u002Fauth\u002Fpasskey",", and ",[137,859,860],{},"\u002Fauth\u002Fjwt"," via facade options.",[100,863,865],{"id":864},"related-modules","Related modules",[766,867,868,872,876,880,884],{},[769,869,870],{},[801,871,59],{"href":60},[769,873,874],{},[801,875,64],{"href":65},[769,877,878],{},[801,879,69],{"href":70},[769,881,882],{},[801,883,74],{"href":75},[769,885,886],{},[801,887,79],{"href":80},[889,890,891],"style",{},"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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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);}",{"title":217,"searchDepth":224,"depth":238,"links":893},[894,895,896,897,898,899,900],{"id":102,"depth":238,"text":103},{"id":200,"depth":238,"text":201},{"id":760,"depth":238,"text":761},{"id":784,"depth":238,"text":154},{"id":806,"depth":238,"text":171},{"id":846,"depth":238,"text":189},{"id":864,"depth":238,"text":865},"Common composition patterns for cookie SPA, Identity bearer, JWT-only, and custom paths.","md",null,{},{"icon":50},{"title":47,"description":901},"HS962TAPj6UJywS48Sca8MpmOfq3d7nJIWon4skBctg",[909,911],{"title":42,"path":43,"stem":44,"description":910,"icon":45,"children":-1},"Hard prerequisites for composing AuthEndpoints modules correctly.",{"title":59,"path":60,"stem":61,"description":912,"icon":62,"children":-1},"Account lifecycle endpoints — register, confirm, forgot\u002Freset password, manage info and 2FA.",1785399440325]