1"use strict";(self.webpackChunkrdc_website=self.webpackChunkrdc_website||[]).push([[6369],{74645(e,t,n){n.d(t,{A:()=>i});n(63696);var a=n(11750),r=n(58116);const s="tabItem_wHwb";var l=n(62540);function o({children:e,className:t,hidden:n}){return(0,l.jsx)("div",{role:"tabpanel",className:(0,a.A)(s,t),hidden:n,children:e})}function i({children:e,className:t,value:n}){const{selectedValue:a,lazy:s}=(0,r.uc)(),i=n===a;return!i&&s?null:(0,l.jsx)(o,{className:t,hidden:!i,children:e})}},6779(e,t,n){n.d(t,{A:()=>b});n(63696);var a=n(11750),r=n(13912),s=n(58116),l=n(63447),o=n(49244);const i="tabList_J5MA",u="tabItem_l0OV";var c=n(62540);function d({className:e}){const{selectedValue:t,selectValue:n,tabValues:r,block:o}=(0,s.uc)(),i=[],{blockElementScrollPositionUntilNextRender:d}=(0,l.a_)(),h=e=>{const a=e.currentTarget,s=i.indexOf(a),l=r[s].value;l!==t&&(d(a),n(l))},p=e=>{let t=null;switch(e.key){case"Enter":h(e);break;case"ArrowRight":{const n=i.indexOf(e.currentTarget)+1;t=i[n]??i[0];break}case"ArrowLeft":{const n=i.indexOf(e.currentTarget)-1;t=i[n]??i[i.length-1];break}}t?.focus()};return(0,c.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":o},e),children:r.map((({value:e,label:n,attributes:r})=>(0,c.jsx)("li",{role:"tab",tabIndex:t===e?0:-1,"aria-selected":t===e,ref:e=>{i.push(e)},onKeyDown:p,onClick:h,...r,className:(0,a.A)("tabs__item",u,r?.className,{"tabs__item--active":t===e}),children:n??e},e)))})}function h({children:e}){return(0,c.jsx)("div",{className:"margin-top--md",children:e})}function p({className:e,children:t}){return(0,c.jsxs)("div",{className:(0,a.A)(r.G.tabs.container,"tabs-container",i),children:[(0,c.jsx)(d,{className:e}),(0,c.jsx)(h,{children:t})]})}function b(e){const t=(0,o.A)(),n=(0,s.OC)(e);return(0,c.jsx)(s.O_,{value:n,children:(0,c.jsx)(p,{className:e.className,children:(0,s.vT)(e.children)})},String(t))}},58116(e,t,n){n.d(t,{OC:()=>b,O_:()=>m,uc:()=>f,vT:()=>c});var a=n(63696),r=n(39853),s=n(76960),l=n(89624),o=n(99866),i=n(66953),u=n(62540);function c(e){return a.Children.toArray(e).filter((e=>"\n"!==e))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??function(e){return a.Children.toArray(e).flatMap((e=>{if(!e)return[];if((0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return[e];const t="string"==typeof e.type?e.type:e.type.name;throw new Error(`Docusaurus error: Bad <Tabs> child <${t}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.\nIf you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.`)})).map((({props:{value:e,label:t,attributes:n,default:a}})=>({value:e,label:t,attributes:n,default:a})))}(n);return function(e){const t=(0,i.XI)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>`'${e.value}'`)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[t,n])}function h({value:e,tabValues:t}){return t.some((t=>t.value===e))}function p({queryString:e=!1,groupId:t}){const n=(0,r.W6)(),s=function({queryString:e=!1,groupId:t}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:e,groupId:t});return[(0,l.aZ)(s),(0,a.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(n.location.search);t.set(s,e),n.replace({...n.location,search:t.toString()})}),[s,n])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,l=d(e),[i,u]=(0,a.useState)((()=>function({defaultValue:e,tabValues:t}){if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!h({value:e,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}const n=t.find((e=>e.default))??t[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:l}))),[c,b]=p({queryString:n,groupId:r}),[g,f]=function({groupId:e}){const t=function(e){return e?`docusaurus.tab.${e}`:null}(e),[n,r]=(0,o.Dv)(t);return[n,(0,a.useCallback)((e=>{t&&r.set(e)}),[t,r])]}({groupId:r}),m=(()=>{const e=c??g;return h({value:e,tabValues:l})?e:null})();(0,s.A)((()=>{m&&u(m)}),[m]);return{selectedValue:i,selectValue:(0,a.useCallback)((e=>{if(!h({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);u(e),b(e),f(e)}),[b,f,l]),tabValues:l,lazy:e.lazy??!1,block:e.block??!1}}const g=(0,a.createContext)(null);function f(){const e=a.useContext(g);if(!e)throw new Error("useTabsContext() must be used within a Tabs component");return e}function m(e){return(0,u.jsx)(g.Provider,{value:e.value,children:e.children})}},31078(e,t,n){n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>l,metadata:()=>a,toc:()=>u});const a=JSON.parse('{"id":"auth","title":"GraphQL Authentication patterns for Reactive Data Client","description":"Cookie Auth","source":"@site/../docs/graphql/auth.md","sourceDirName":".","slug":"/auth","permalink":"/graphql/auth","draft":false,"unlisted":false,"editUrl":"https://github.com/reactive/data-client/edit/master/docs/graphql/auth.md","tags":[],"version":"current","lastUpdatedBy":"Nathaniel Tucker","lastUpdatedAt":1741607507000,"frontMatter":{"title":"GraphQL Authentication patterns for Reactive Data Client","sidebar_label":"Authentication"},"sidebar":"docs","previous":{"title":"Usage","permalink":"/graphql/"},"next":{"title":"GQLEndpoint","permalink":"/graphql/api/GQLEndpoint"}}');var r=n(62540),s=n(43023);n(6779),n(74645);const l={title:"GraphQL Authentication patterns for Reactive Data Client",sidebar_label:"Authentication"},o="GraphQL Authentication",i={}
1,u=[{value:"Cookie Auth",id:"cookie-auth",level:2},{value:"Access Tokens",id:"access-tokens",level:2},{value:"401 Logout Handling",id:"401-logout-handling",level:2}];function c(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"graphql-authentication",children:"GraphQL Authentication"})}),"\n",(0,r.jsx)(t.h2,{id:"cookie-auth",children:"Cookie Auth"}),"\n",(0,r.jsx)(t.p,{children:"Here's an example using simple cookie auth:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",metastring:'title="schema/endpoint.ts"',children:"export const gql = new GQLEndpoint('https://nosy-baritone.glitch.me', {\n getRequestInit(body: any): Promise<RequestInit> {\n return {\n ...super.getRequestInit(body),\n credentials: 'same-origin',\n };\n }\n});\nexport default gql;\n"})}),"\n",(0,r.jsx)(t.h2,{id:"access-tokens",children:"Access Tokens"}),"\n",(0,r.jsx)(t.p,{children:"Here we'll use a member variable to track the access token and send it\nin a header."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",metastring:'title="schema/endpoint.ts"',children:"export const gql = new GQLEndpoint('https://nosy-baritone.glitch.me', {\n getHeaders(headers: HeadersInit): HeadersInit {\n return {\n ...headers,\n 'Access-Token': this.accessToken,\n };\n },\n});\nexport default gql;\n"})}),"\n",(0,r.jsx)(t.p,{children:"Then be sure to set the access token upon login:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"import gql from 'schema/endpoint';\n\nfunction Auth() {\n const handleLogin = useCallback(\n async e => {\n const { accessToken } = await login(new FormData(e.target));\n // success!\n // highlight-next-line\n gql.accessToken = accessToken;\n },\n [login],\n );\n\n return <AuthForm onSubmit={handleLogin} />;\n}\n"})}),"\n",(0,r.jsx)(t.h2,{id:"401-logout-handling",children:"401 Logout Handling"}),"\n",(0,r.jsxs)(t.p,{children:["In case a users authorization expires, the server will typically responsd to indicate\nas such. The standard way of doing this is with a 401. ",(0,r.jsx)(t.a,{href:"/docs/api/LogoutManager",children:"LogoutManager"}),"\ncan be used to easily trigger any de-authorization cleanup."]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.