[{"data":1,"prerenderedAt":849},["ShallowReactive",2],{"navigation":3,"-adapters":167,"-adapters-surround":846},[4,22,78,106,141,148],{"title":5,"path":6,"stem":7,"children":8},"Introduction","\u002Fgetting-started","0.Getting-Started\u002F0.index",[9,10,14,18],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"Installation","\u002Fgetting-started\u002Finstallation","0.Getting-Started\u002F1.installation",{"title":15,"path":16,"stem":17},"Quickstart","\u002Fgetting-started\u002Fquickstart","0.Getting-Started\u002F2.quickstart",{"title":19,"path":20,"stem":21},"Core concepts","\u002Fgetting-started\u002Fcore-concepts","0.Getting-Started\u002F3.core-concepts",{"title":23,"path":24,"stem":25,"children":26,"icon":28},"JWT","\u002Fjwt","1.JWT\u002F0.index",[27,29,52],{"title":23,"path":24,"stem":25,"icon":28},"i-carbon-certificate",{"title":30,"path":31,"stem":32,"children":33,"icon":35},"JWS","\u002Fjwt\u002Fjws","1.JWT\u002F1.JWS\u002F0.index",[34,36,40,44,48],{"title":30,"path":31,"stem":32,"icon":35},"i-carbon-document-signed",{"title":37,"path":38,"stem":39},"Signing","\u002Fjwt\u002Fjws\u002Fsigning","1.JWT\u002F1.JWS\u002F1.signing",{"title":41,"path":42,"stem":43},"Verifying","\u002Fjwt\u002Fjws\u002Fverifying","1.JWT\u002F1.JWS\u002F2.verifying",{"title":45,"path":46,"stem":47},"Multi-signature","\u002Fjwt\u002Fjws\u002Fmulti-signature","1.JWT\u002F1.JWS\u002F3.multi-signature",{"title":49,"path":50,"stem":51},"Algorithms","\u002Fjwt\u002Fjws\u002Falgorithms","1.JWT\u002F1.JWS\u002F4.algorithms",{"title":53,"path":54,"stem":55,"children":56,"icon":58},"JWE","\u002Fjwt\u002Fjwe","1.JWT\u002F2.JWE\u002F0.index",[57,59,63,67,71,75],{"title":53,"path":54,"stem":55,"icon":58},"i-carbon-locked",{"title":60,"path":61,"stem":62},"Encrypting","\u002Fjwt\u002Fjwe\u002Fencrypting","1.JWT\u002F2.JWE\u002F1.encrypting",{"title":64,"path":65,"stem":66},"Decrypting","\u002Fjwt\u002Fjwe\u002Fdecrypting","1.JWT\u002F2.JWE\u002F2.decrypting",{"title":68,"path":69,"stem":70},"Multi-recipient","\u002Fjwt\u002Fjwe\u002Fmulti-recipient","1.JWT\u002F2.JWE\u002F3.multi-recipient",{"title":72,"path":73,"stem":74},"ECDH-ES and end-to-end encryption","\u002Fjwt\u002Fjwe\u002Fecdh-es","1.JWT\u002F2.JWE\u002F4.ecdh-es",{"title":49,"path":76,"stem":77},"\u002Fjwt\u002Fjwe\u002Falgorithms","1.JWT\u002F2.JWE\u002F5.algorithms",{"title":79,"path":80,"stem":81,"children":82,"icon":84},"Examples","\u002Fexamples","10.Examples\u002F0.index",[83,85,90,94,98,102],{"title":79,"path":80,"stem":81,"icon":84},"i-carbon-code-reference",{"title":86,"path":87,"stem":88,"icon":89},"Authentication basics","\u002Fexamples\u002Fauthentication-basics","10.Examples\u002F1.authentication-basics","i-lucide-code",{"title":91,"path":92,"stem":93,"icon":89},"Consuming a JWKS endpoint","\u002Fexamples\u002Fjwks-endpoint","10.Examples\u002F2.jwks-endpoint",{"title":95,"path":96,"stem":97,"icon":89},"Refresh token pattern","\u002Fexamples\u002Frefresh-token-pattern","10.Examples\u002F3.refresh-token-pattern",{"title":99,"path":100,"stem":101,"icon":89},"End-to-end encryption","\u002Fexamples\u002Fend-to-end-encryption","10.Examples\u002F4.end-to-end-encryption",{"title":103,"path":104,"stem":105,"icon":89},"Signed receipts","\u002Fexamples\u002Fsigned-receipts","10.Examples\u002F5.signed-receipts",{"title":107,"path":108,"stem":109,"children":110,"icon":112},"JWK","\u002Fjwk","2.JWK\u002F0.index",[111,113,117,121,125,129,133,137],{"title":107,"path":108,"stem":109,"icon":112},"i-carbon-two-factor-authentication",{"title":114,"path":115,"stem":116},"Generating keys","\u002Fjwk\u002Fgenerating","2.JWK\u002F1.generating",{"title":118,"path":119,"stem":120},"Importing and exporting","\u002Fjwk\u002Fimport-export","2.JWK\u002F2.import-export",{"title":122,"path":123,"stem":124},"PEM conversion","\u002Fjwk\u002Fpem","2.JWK\u002F3.pem",{"title":126,"path":127,"stem":128},"Key wrapping","\u002Fjwk\u002Fwrapping","2.JWK\u002F4.wrapping",{"title":130,"path":131,"stem":132},"Password derivation","\u002Fjwk\u002Fpassword-derivation","2.JWK\u002F5.password-derivation",{"title":134,"path":135,"stem":136},"JWK Sets","\u002Fjwk\u002Fjwk-sets","2.JWK\u002F6.jwk-sets",{"title":138,"path":139,"stem":140},"JWK cache","\u002Fjwk\u002Fcache","2.JWK\u002F7.cache",{"title":142,"path":143,"stem":144,"children":145,"icon":147},"Utilities","\u002Futilities","3.Utilities\u002F0.index",[146],{"title":142,"path":143,"stem":144,"icon":147},"i-carbon-tool-box",{"title":149,"path":150,"stem":151,"children":152,"icon":154},"Adapters","\u002Fadapters","99.Adapters\u002F0.index",[153,155,159,163],{"title":149,"path":150,"stem":151,"icon":154},"i-carbon-plug",{"title":156,"path":157,"stem":158},"H3 sessions","\u002Fadapters\u002Fh3-sessions","99.Adapters\u002F1.h3-sessions",{"title":160,"path":161,"stem":162},"Lifecycle hooks","\u002Fadapters\u002Fhooks","99.Adapters\u002F2.hooks",{"title":164,"path":165,"stem":166},"Lower-level functions","\u002Fadapters\u002Flower-level","99.Adapters\u002F3.lower-level",{"id":168,"title":149,"body":169,"description":450,"extension":841,"meta":842,"navigation":843,"path":150,"seo":844,"stem":151,"__hash__":845},"content\u002F99.Adapters\u002F0.index.md",{"type":170,"value":171,"toc":835,"icon":154},"minimark",[172,201,204,265,272,289,294,297,335,399,402,428,432,444,692,710,714,797,801,831],[173,174,175,176,180,181,188,189,194,195,200],"p",{},"unjwt ships cookie-based ",[177,178,179],"strong",{},"session adapters"," for ",[182,183,187],"a",{"href":184,"rel":185},"https:\u002F\u002Fh3.dev",[186],"nofollow","H3"," — the tiny universal HTTP framework behind ",[182,190,193],{"href":191,"rel":192},"https:\u002F\u002Fnuxt.com",[186],"Nuxt"," and ",[182,196,199],{"href":197,"rel":198},"https:\u002F\u002Fnitro.build",[186],"Nitro",". Both H3 v1 and v2 are supported (used by different Nuxt \u002F Nitro major versions).",[173,202,203],{},"Import paths:",[205,206,207,220],"table",{},[208,209,210],"thead",{},[211,212,213,217],"tr",{},[214,215,216],"th",{},"Path",[214,218,219],{},"Framework",[221,222,223,238,251],"tbody",{},[211,224,225,232],{},[226,227,228],"td",{},[229,230,231],"code",{},"unjwt\u002Fadapters\u002Fh3v1",[226,233,234,237],{},[177,235,236],{},"H3 v1"," — Nuxt v4, Nitro v2",[211,239,240,245],{},[226,241,242],{},[229,243,244],{},"unjwt\u002Fadapters\u002Fh3v2",[226,246,247,250],{},[177,248,249],{},"H3 v2"," — Nuxt v5, Nitro v3",[211,252,253,258],{},[226,254,255],{},[229,256,257],{},"unjwt\u002Fadapters\u002Fh3",[226,259,260,261,264],{},"Alias for ",[229,262,263],{},"h3v1"," (will flip to v2 in a future major release)",[173,266,267,268,271],{},"All three export the same API surface. The internal difference is which ",[229,269,270],{},"h3"," peer dependency they're compiled against.",[273,274,275],"note",{},[173,276,277,278,280,281,284,285,288],{},"Peer dep: ",[229,279,270],{}," — ",[229,282,283],{},"^1.15.4"," for v1, ",[229,286,287],{},">=2.0.1-rc.20 || ^2.0.1"," for v2.",[290,291,293],"h2",{"id":292},"jwe-vs-jws-sessions","JWE vs JWS sessions",[173,295,296],{},"Each adapter provides two entry points:",[205,298,299,309],{},[208,300,301],{},[211,302,303,306],{},[214,304,305],{},"Function",[214,307,308],{},"Session storage",[221,310,311,323],{},[211,312,313,320],{},[226,314,315],{},[182,316,317],{"href":157},[229,318,319],{},"useJWESession",[226,321,322],{},"JWE — encrypted, opaque to the client.",[211,324,325,332],{},[226,326,327],{},[182,328,329],{"href":157},[229,330,331],{},"useJWSSession",[226,333,334],{},"JWS — signed, readable by the client.",[205,336,337,349],{},[208,338,339],{},[211,340,341,343,346],{},[214,342],{},[214,344,345],{},"JWE (encrypted)",[214,347,348],{},"JWS (signed)",[221,350,351,362,377,388],{},[211,352,353,356,359],{},[226,354,355],{},"Data visibility",[226,357,358],{},"Encrypted, not readable by client",[226,360,361],{},"Base64URL-encoded, readable by anyone",[211,363,364,367,372],{},[226,365,366],{},"Default cookie",[226,368,369],{},[229,370,371],{},"httpOnly: true, secure: true",[226,373,374],{},[229,375,376],{},"httpOnly: false, secure: true",[211,378,379,382,385],{},[226,380,381],{},"Key types",[226,383,384],{},"Password string, symmetric JWK, asymmetric keypair",[226,386,387],{},"Symmetric JWK, asymmetric keypair",[211,389,390,393,396],{},[226,391,392],{},"Use when",[226,394,395],{},"Session data is sensitive",[226,397,398],{},"Data is non-sensitive; clients need to read it",[173,400,401],{},"Rule of thumb:",[403,404,405,412,418],"ul",{},[406,407,408,411],"li",{},[177,409,410],{},"Login \u002F refresh tokens"," — JWE. The client shouldn't inspect them, and they often contain user-identifiable data.",[406,413,414,417],{},[177,415,416],{},"Session data the UI should render from"," — JWS. Things like role, display name, theme — readable, tamper-evident.",[406,419,420,423,424,427],{},[177,421,422],{},"Mixing both"," — common in practice. See the ",[182,425,426],{"href":96},"refresh-token pattern",".",[290,429,431],{"id":430},"the-session-manager","The session manager",[173,433,434,435,194,437,439,440,443],{},"Both ",[229,436,319],{},[229,438,331],{}," return a ",[229,441,442],{},"SessionManager",":",[445,446,451],"pre",{"className":447,"code":448,"language":449,"meta":450,"style":450},"language-ts shiki shiki-themes github-light github-dark github-dark","interface SessionManager\u003CT, ConfigMaxAge> {\n  readonly id: string | undefined; \u002F\u002F from jti — undefined until update() is called\n  readonly createdAt: number; \u002F\u002F from iat, in ms\n  readonly expiresAt: ConfigMaxAge extends ExpiresIn ? number : number | undefined;\n  readonly data: SessionData\u003CT>; \u002F\u002F session payload (excludes jti\u002Fiat\u002Fexp)\n  readonly token: string | undefined; \u002F\u002F current raw JWT token\n  update: (update?: SessionUpdate\u003CT>) => Promise\u003CSessionManager\u003CT, ConfigMaxAge>>;\n  clear: () => Promise\u003CSessionManager\u003CT, ConfigMaxAge>>;\n}\n","ts","",[229,452,453,482,511,529,565,588,609,657,686],{"__ignoreMap":450},[454,455,458,462,466,470,473,476,479],"span",{"class":456,"line":457},"line",1,[454,459,461],{"class":460},"so5gQ","interface",[454,463,465],{"class":464},"shcOC"," SessionManager",[454,467,469],{"class":468},"slsVL","\u003C",[454,471,472],{"class":464},"T",[454,474,475],{"class":468},", ",[454,477,478],{"class":464},"ConfigMaxAge",[454,480,481],{"class":468},"> {\n",[454,483,485,488,492,494,498,501,504,507],{"class":456,"line":484},2,[454,486,487],{"class":460},"  readonly",[454,489,491],{"class":490},"sQHwn"," id",[454,493,443],{"class":460},[454,495,497],{"class":496},"suiK_"," string",[454,499,500],{"class":460}," |",[454,502,503],{"class":496}," undefined",[454,505,506],{"class":468},"; ",[454,508,510],{"class":509},"sCsY4","\u002F\u002F from jti — undefined until update() is called\n",[454,512,514,516,519,521,524,526],{"class":456,"line":513},3,[454,515,487],{"class":460},[454,517,518],{"class":490}," createdAt",[454,520,443],{"class":460},[454,522,523],{"class":496}," number",[454,525,506],{"class":468},[454,527,528],{"class":509},"\u002F\u002F from iat, in ms\n",[454,530,532,534,537,539,542,545,548,551,553,556,558,560,562],{"class":456,"line":531},4,[454,533,487],{"class":460},[454,535,536],{"class":490}," expiresAt",[454,538,443],{"class":460},[454,540,541],{"class":464}," ConfigMaxAge",[454,543,544],{"class":460}," extends",[454,546,547],{"class":464}," ExpiresIn",[454,549,550],{"class":460}," ?",[454,552,523],{"class":496},[454,554,555],{"class":460}," :",[454,557,523],{"class":496},[454,559,500],{"class":460},[454,561,503],{"class":496},[454,563,564],{"class":468},";\n",[454,566,568,570,573,575,578,580,582,585],{"class":456,"line":567},5,[454,569,487],{"class":460},[454,571,572],{"class":490}," data",[454,574,443],{"class":460},[454,576,577],{"class":464}," SessionData",[454,579,469],{"class":468},[454,581,472],{"class":464},[454,583,584],{"class":468},">; ",[454,586,587],{"class":509},"\u002F\u002F session payload (excludes jti\u002Fiat\u002Fexp)\n",[454,589,591,593,596,598,600,602,604,606],{"class":456,"line":590},6,[454,592,487],{"class":460},[454,594,595],{"class":490}," token",[454,597,443],{"class":460},[454,599,497],{"class":496},[454,601,500],{"class":460},[454,603,503],{"class":496},[454,605,506],{"class":468},[454,607,608],{"class":509},"\u002F\u002F current raw JWT token\n",[454,610,612,615,617,620,623,626,629,631,633,636,639,642,644,646,648,650,652,654],{"class":456,"line":611},7,[454,613,614],{"class":464},"  update",[454,616,443],{"class":460},[454,618,619],{"class":468}," (",[454,621,622],{"class":490},"update",[454,624,625],{"class":460},"?:",[454,627,628],{"class":464}," SessionUpdate",[454,630,469],{"class":468},[454,632,472],{"class":464},[454,634,635],{"class":468},">) ",[454,637,638],{"class":460},"=>",[454,640,641],{"class":464}," Promise",[454,643,469],{"class":468},[454,645,442],{"class":464},[454,647,469],{"class":468},[454,649,472],{"class":464},[454,651,475],{"class":468},[454,653,478],{"class":464},[454,655,656],{"class":468},">>;\n",[454,658,660,663,665,668,670,672,674,676,678,680,682,684],{"class":456,"line":659},8,[454,661,662],{"class":464},"  clear",[454,664,443],{"class":460},[454,666,667],{"class":468}," () ",[454,669,638],{"class":460},[454,671,641],{"class":464},[454,673,469],{"class":468},[454,675,442],{"class":464},[454,677,469],{"class":468},[454,679,472],{"class":464},[454,681,475],{"class":468},[454,683,478],{"class":464},[454,685,656],{"class":468},[454,687,689],{"class":456,"line":688},9,[454,690,691],{"class":468},"}\n",[173,693,694,695,280,698,701,702,705,706,709],{},"Sessions are ",[177,696,697],{},"lazy",[229,699,700],{},"session.id"," is ",[229,703,704],{},"undefined"," until you call ",[229,707,708],{},"session.update()",". This is intentional: it matches OAuth and spec-compliant flows where a session only exists once a valid operation has created it.",[290,711,713],{"id":712},"what-else-the-adapters-do","What else the adapters do",[403,715,716,722,732,751,764,779],{},[406,717,718,721],{},[177,719,720],{},"Automatic cookie chunking"," for large tokens (essential for JWE with claims that exceed 4KB).",[406,723,724,727,728,731],{},[177,725,726],{},"Header-based token extraction"," as an alternative to cookies (",[229,729,730],{},"Authorization: Bearer ...",").",[406,733,734,280,736,475,739,475,742,475,745,475,748,427],{},[177,735,160],{},[229,737,738],{},"onRead",[229,740,741],{},"onUpdate",[229,743,744],{},"onClear",[229,746,747],{},"onExpire",[229,749,750],{},"onError",[406,752,753,280,756,759,760,763],{},[177,754,755],{},"Key-lookup hooks",[229,757,758],{},"onVerifyKeyLookup"," (JWS) \u002F ",[229,761,762],{},"onUnsealKeyLookup"," (JWE) for key rotation.",[406,765,766,280,769,475,772,475,775,778],{},[177,767,768],{},"Lower-level helpers",[229,770,771],{},"getJWESession",[229,773,774],{},"sealJWESession",[229,776,777],{},"unsealJWESession",", etc., when you need manual control.",[406,780,781,280,784,475,787,475,790,475,793,796],{},[177,782,783],{},"Re-exported helpers",[229,785,786],{},"generateJWK",[229,788,789],{},"importPEM",[229,791,792],{},"exportPEM",[229,794,795],{},"deriveJWKFromPassword"," for convenience.",[290,798,800],{"id":799},"going-further","Going further",[403,802,803,814,820,826],{},[406,804,805,280,808,810,811,813],{},[182,806,807],{"href":157},"H3 sessions →",[229,809,319],{}," \u002F ",[229,812,331],{}," configuration in detail.",[406,815,816,819],{},[182,817,818],{"href":161},"Lifecycle hooks →"," — logging, revocation, key rotation.",[406,821,822,825],{},[182,823,824],{"href":165},"Lower-level functions →"," — manual session control.",[406,827,828,427],{},[182,829,830],{"href":96},"Example: refresh token pattern →",[832,833,834],"style",{},"html pre.shiki code .so5gQ, html code.shiki .so5gQ{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .shcOC, html code.shiki .shcOC{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .slsVL, html code.shiki .slsVL{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sQHwn, html code.shiki .sQHwn{--shiki-light:#E36209;--shiki-default:#FFAB70;--shiki-dark:#FFAB70}html pre.shiki code .suiK_, html code.shiki .suiK_{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}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":450,"searchDepth":484,"depth":484,"links":836},[837,838,839,840],{"id":292,"depth":484,"text":293},{"id":430,"depth":484,"text":431},{"id":712,"depth":484,"text":713},{"id":799,"depth":484,"text":800},"md",{"icon":154},{"icon":154},{"title":149,"description":450},"Rcp2gcDKlRn3Rfh5nsLKO5P92L5H8U00yZRQgcjbS1U",[847,848],{"title":142,"path":143,"stem":144,"description":450,"icon":147,"children":-1},{"title":156,"path":157,"stem":158,"description":450,"children":-1},1776888557913]