text: (window.webpackJsonp=window.webpackJsonp||[]).push([[233],{297:function(e,n,t){"use strict";t.r(n),t.d(n,"frontMatter",(function(){return p})),t.d(n,"metadata",(function(){return f})),t.d(n,"rightToc",(function(){return m})),t.d(n,"default",(function(){return g}));var a=t(3),i=t(7),o=(t(0),t(442)),r=t(443),s=t(474),l=t(475),c=t(476),d=t(477),u=t(631),b=t(481),p={id:"user-login",title:"User Login"},f={unversionedId:"self-service/flows/user-login",id:"version-v0.5/self-service/flows/user-login",isDocsHomePage:!1,title:"User Login",description:"import {",source:"@site/versioned_docs/version-v0.5/self-service/flows/user-login.mdx",slug:"/self-service/flows/user-login",permalink:"/kratos/docs/self-service/flows/user-login",editUrl:"https://github.com/ory/kratos/edit/master/docs/versioned_docs/version-v0.5/self-service/flows/user-login.mdx",version:"v0.5",lastUpdatedBy:"aeneasr",lastUpdatedAt:1605099704,sidebar:"version-v0.5/docs",previous:{title:"User Registration",permalink:"/kratos/docs/self-service/flows/user-registration"},next:{title:"User Settings and Profile Updates",permalink:"/kratos/docs/self-service/flows/user-settings"}},m=[{value:"Initialize Login Flow",id:"initialize-login-flow",children:[{value:"Login for Browser Clients",id:"login-for-browser-clients",children:[]},{value:"Login for API Clients",id:"login-for-api-clients",children:[]}]},{value:"Login Flow Payloads",id:"login-flow-payloads",children:[{value:"Login with Username/Email and Password",id:"login-with-usernameemail-and-password",children:[]},{value:"Login with Google, Facebook, GitHub, ..., OpenID Connect / OAuth 2.0",id:"login-with-google-facebook-github--openid-connect--oauth-20",children:[]}]},{value:"Login Flow Form Rendering",id:"login-flow-form-rendering",children:[]},{value:"Login Form Validation",id:"login-form-validation",children:[{value:"Login with Username/Email and Password",id:"login-with-usernameemail-and-password-1",children:[]},{value:"Login with Google, Facebook, GitHub, ..., OpenID Connect / OAuth 2.0",id:"login-with-google-facebook-github--openid-connect--oauth-20-1",children:[]}]},{value:"Successful Login",id:"successful-login",children:[{value:"Browser Clients",id:"browser-clients",children:[]},{value:"API Clients",id:"api-clients",children:[]}]},{value:"Refreshing a Session",id:"refreshing-a-session",children:[]},{value:"Hooks",id:"hooks",children:[]}],h={rightToc:m};function g(e){var n=e.components,t=Object(i.a)(e,["components"]);return Object(o.b)("wrapper",Object(a.a)({},h,t,{components:n,mdxType:"MDXLayout"}),Object(o.b)("div",{className:"admonition admonition-info alert alert--info"},Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-heading"}),Object(o.b)("h5",{parentName:"div"},Object(o.b)("span",Object(a.a)({parentName:"h5"},{className:"admonition-icon"}),Object(o.b)("svg",Object(a.a)({parentName:"span"},{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"16",viewBox:"0 0 14 16"}),Object(o.b)("path",Object(a.a)({parentName:"svg"},{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})))),"info")),Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-content"}),Object(o.b)("p",{parentName:"div"},"Please read the ",Object(o.b)("a",Object(a.a)({parentName:"p"},{href:"../../self-service"}),"Self-Service Flows")," overview before\ncontinuing with this document."))),Object(o.b)("p",null,"There are two Login Flow types supported in ORY Kratos:"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},"Flows where the user sits in front of the Browser (e.g. website, single page\napp, ...)"),Object(o.b)("li",{parentName:"ul"},"Flows where API interaction is required (e.g. mobile app, Smart TV, ...)")),Object(o.b)("p",null,"The Login Flow can be summarized as the following state machine:"),Object(o.b)(r.a,{chart:'\nstateDiagram\n  s1: Flow is initialized\n  s2: Execute Before Login Hook(s)\n  s3: User Interface renders Login Flow Forms\n  s4: Execute After Login Hook(s)\n  s5: Update Login Flow with Error Context(s)\n  s6: Login successful\n\t[*] --\x3e s1 : User clicks "Log in"\n  s1 --\x3e s2\n  s2 --\x3e Error : A hook fails\n  s2 --\x3e s3\n  s3 --\x3e s4 : User provides valid credentials data\n  s3 --\x3e s5 : User provides invalid credentials data\n  s5 --\x3e s3\n  s4 --\x3e Error : A hook fails\n  s4 --\x3e s6\n  s6 --\x3e [*]\n  Error --\x3e [*]\n',mdxType:"Mermaid"}),Object(o.b)("p",null,"Currently, two login methods are supported:"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"password")," for signing in with an email / username and password;"),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"oidc")," for signing in using a social sign in provider such as Google or\nFacebook (check out the\n",Object(o.b)("a",Object(a.a)({parentName:"li"},{href:"/kratos/docs/guides/sign-in-with-github-google-facebook-linkedin"}),"set up guide"),").")),Object(o.b)("p",null,"Both are dis/enabled in the ORY Kratos config:"),Object(o.b)("pre",null,Object(o.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml",metastring:'title="path/to/my/kratos/config.yml"',title:'"path/to/my/kratos/config.yml"'}),"selfservice:\n  methods:\n    password:\n      enabled: true\n    oidc:\n      enabled: true\n      # ...\n")),Object(o.b)("h2",{id:"initialize-login-flow"},"Initialize Login Flow"),Object(o.b)("p",null,"The first step is to initialize the Login Flow. This allows pre-login hooks to\nrun, set up Anti-CSRF tokens, and more."),Object(o.b)("h3",{id:"login-for-browser-clients"},"Login for Browser Clients"),Object(o.b)("p",null,"The Login Flow for browser clients relies on HTTP redirects between ORY Kratos,\nyour Login UI, and the end-user's browser:"),Object(o.b)(l.a,{flows:["login"],success:"Set session cookie",interactions:['"Log in"'],mdxType:"SelfServiceBrowserFlow"}),Object(o.b)("p",null,"To initialize the Login Flow, point the Browser to the initialization endpoint:"),Object(o.b)(d.a,{items:u.e,mdxType:"CodeTabs"}),Object(o.b)("p",null,"The server responds with a HTTP 302 redirect to the Login UI, appending the\n",Object(o.b)("inlineCode",{parentName:"p"},"?flow=<flow-id>")," query parameter (see the curl example) to the URL configured\nhere:"),Object(o.b)("pre",null,Object(o.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml",metastring:'title="path/to/config/kratos.yml"',title:'"path/to/config/kratos.yml"'}),"selfservice:\n  flows:\n    login:\n      # becomes http://127.0.0.1:4455/auth/login?flow=df607aa1-d555-4b2a-b3e4-0f5a1d2fe6f3\n      ui_url: http://127.0.0.1:4455/auth/login\n")),Object(o.b)("h3",{id:"login-for-api-clients"},"Login for API Clients"),Object(o.b)(s.a,{mdxType:"ApiWarning"}),Object(o.b)("p",null,"The Login Flow for API clients does not use HTTP Redirects and can be summarized\nas follows:"),Object(o.b)(c.a,{flows:["login"],success:"Return login session token",interactions:['"Log in"'],mdxType:"SelfServiceApiFlow"}),Object(o.b)("p",null,"To initialize the API flow, the client calls the API-flow initialization\nendpoint\n(",Object(o.b)("a",Object(a.a)({parentName:"p"},{href:"/kratos/docs/reference/api#initialize-login-flow-for-api-clients"}),"REST API Reference"),")\nwhich returns a JSON response:"),Object(o.b)(d.a,{items:u.d,mdxType:"CodeTabs"}),Object(o.b)("h2",{id:"login-flow-payloads"},"Login Flow Payloads"),Object(o.b)("p",null,"Fetching the Login Flow\n(",Object(o.b)("a",Object(a.a)({parentName:"p"},{href:"/kratos/docs/reference/api#get-login-flow"}),"REST API Reference"),") is usually only\nrequired for browser clients but also works for Login Flows initialized by API\nclients. All you need is a valid flow ID:"),Object(o.b)(d.a,{items:u.a,mdxType:"CodeTabs"}),Object(o.b)("h3",{id:"login-with-usernameemail-and-password"},"Login with Username/Email and Password"),Object(o.b)("div",{className:"admonition admonition-tip alert alert--success"},Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-heading"}),Object(o.b)("h5",{parentName:"div"},Object(o.b)("span",Object(a.a)({parentName:"h5"},{className:"admonition-icon"}),Object(o.b)("svg",Object(a.a)({parentName:"span"},{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"16",viewBox:"0 0 12 16"}),Object(o.b)("path",Object(a.a)({parentName:"svg"},{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})))),"Before you start")),Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-content"}),Object(o.b)("p",{parentName:"div"},"Please read the\n",Object(o.b)("a",Object(a.a)({parentName:"p"},{href:"../../concepts/credentials/username-email-password"}),"Username / Email & Password Credentials Documentation"),"\nfirst."))),Object(o.b)("p",null,"When the ",Object(o.b)("inlineCode",{parentName:"p"},"password")," method is enabled, it will be part of the ",Object(o.b)("inlineCode",{parentName:"p"},"methods")," payload\nin the Login Flow:"),Object(o.b)("pre",null,Object(o.b)("code",Object(a.a)({parentName:"pre"},{className:"language-shell",metastring:"script",script:!0}),'$ curl -H "Accept: application/json" -s \\\n  \'http://127.0.0.1:4434/self-service/login/flows?id=26ac2d66-eeb7-42f3-8ba8-5fe70925d6a3\' \\\n  | jq -r \'.methods.password.config\'\n\n{\n  "action": "http://127.0.0.1:4433/self-service/login/methods/password?flow=26ac2d66-eeb7-42f3-8ba8-5fe70925d6a3",\n  "method": "POST",\n  "fields": [\n    {\n      "name": "identifier",\n      "type": "text",\n      "required": true,\n      "value": ""\n    },\n    {\n      "name": "password",\n      "type": "password",\n      "required": true\n    },\n    {\n      "name": "csrf_token",\n      "type": "hidden",\n      "required": true,\n      "value": "Bo72oeXYFnjZj2B9Ple+GZBkn5oqQZDACcYvGeUi8J48R9+yRk1KBagov/nJ/jbfBgugsMUzYMf4VpGNThkjgw=="\n    }\n  ]\n}\n')),Object(o.b)("h3",{id:"login-with-google-facebook-github--openid-connect--oauth-20"},"Login with Google, Facebook, GitHub, ..., OpenID Connect / OAuth 2.0"),Object(o.b)("div",{className:"admonition admonition-tip alert alert--success"},Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-heading"}),Object(o.b)("h5",{parentName:"div"},Object(o.b)("span",Object(a.a)({parentName:"h5"},{className:"admonition-icon"}),Object(o.b)("svg",Object(a.a)({parentName:"span"},{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"16",viewBox:"0 0 12 16"}),Object(o.b)("path",Object(a.a)({parentName:"svg"},{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})))),"Before you start")),Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-content"}),Object(o.b)("p",{parentName:"div"},"Check out the\n",Object(o.b)("a",Object(a.a)({parentName:"p"},{href:"/kratos/docs/guides/sign-in-with-github-google-facebook-linkedin"}),"Sign in with GitHub, Google, ... Guide"),"\nand learn how to set up this method!"))),Object(o.b)("p",null,"The Social Sign In Method (",Object(o.b)("inlineCode",{parentName:"p"},"oidc"),") enables you to use"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},Object(o.b)("a",Object(a.a)({parentName:"li"},{href:"http://github.com/"}),"GitHub"),";"),Object(o.b)("li",{parentName:"ul"},Object(o.b)("a",Object(a.a)({parentName:"li"},{href:"https://developer.apple.com/sign-in-with-apple/"}),"Apple"),";"),Object(o.b)("li",{parentName:"ul"},Object(o.b)("a",Object(a.a)({parentName:"li"},{href:"https://docs.gitlab.com/ee/integration/openid_connect_provider.html"}),"GitLab"),";"),Object(o.b)("li",{parentName:"ul"},Object(o.b)("a",Object(a.a)({parentName:"li"},{href:"https://developers.google.com/identity/sign-in/web/sign-in"}),"Google"),";"),Object(o.b)("li",{parentName:"ul"},Object(o.b)("a",Object(a.a)({parentName:"li"},{href:"https://developers.facebook.com/docs/facebook-login/"}),"Facebook"),";"),Object(o.b)("li",{parentName:"ul"},Object(o.b)("a",Object(a.a)({parentName:"li"},{href:"https://www.ory.sh/hydra"}),"ORY Hydra"),";"),Object(o.b)("li",{parentName:"ul"},Object(o.b)("a",Object(a.a)({parentName:"li"},{href:"https://www.keycloak.org"}),"Keycloak"),";"),Object(o.b)("li",{parentName:"ul"},"and every other OpenID Connect Certified Provider")),Object(o.b)("div",{className:"admonition admonition-warning alert alert--danger"},Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-heading"}),Object(o.b)("h5",{parentName:"div"},Object(o.b)("span",Object(a.a)({parentName:"h5"},{className:"admonition-icon"}),Object(o.b)("svg",Object(a.a)({parentName:"span"},{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"16",viewBox:"0 0 12 16"}),Object(o.b)("path",Object(a.a)({parentName:"svg"},{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})))),"warning")),Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-content"}),Object(o.b)("p",{parentName:"div"},"Social Sign In is currently not possible for API Clients. It will be possible in\na future version, which is partially tracked as\n",Object(o.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/ory/kratos/issues/273"}),"kratos#273")))),Object(o.b)("p",null,"If enabled, the method contains an ",Object(o.b)("inlineCode",{parentName:"p"},"oidc")," key with the configured sign in\nproviders as submit fields:"),Object(o.b)("pre",null,Object(o.b)("code",Object(a.a)({parentName:"pre"},{className:"language-shell",metastring:"script",script:!0}),'$ curl -H "Accept: application/json" -s \\\n  \'http://127.0.0.1:4434/self-service/login/flows?id=26ac2d66-eeb7-42f3-8ba8-5fe70925d6a3\' \\\n  | jq -r \'.methods.oidc.config\'\n\n{\n  "action": "http://127.0.0.1:4433/self-service/methods/oidc/auth/7430f336-0be0-47d1-b1fc-5cc6fcc3f228",\n  "method": "POST",\n  "fields": [\n    {\n      "name": "csrf_token",\n      "type": "hidden",\n      "required": true,\n      "value": "LJ3o59zXjukFs1004vyn3QrWDrfutW2e0Iaqo/9Ck6srYAceydRr59GEZJNFY6Walnell+r10/DlXUy/Eq6sXQ=="\n    },\n    {\n      "name": "provider",\n      "type": "submit",\n      "value": "github"\n    }\n  ]\n}\n')),Object(o.b)("h2",{id:"login-flow-form-rendering"},"Login Flow Form Rendering"),Object(o.b)("p",null,"The Login User Interface is a route (page / site) in your application (server,\nnative app, single page app) that should render a login form."),Object(o.b)("p",null,"In stark contrast to other Identity Systems, ORY Kratos does not render this\nHTML. Instead, you need to implement the HTML code in your application (e.g.\nNodeJS + ExpressJS, Java, PHP, ReactJS, ...), which gives you extreme\nflexibility and customizability in your user interface flows and designs."),Object(o.b)("p",null,"You will use the Login Flow JSON response to render the login form UI, which\ncould looks as follows depending on your programming language and web framework:"),Object(o.b)(b.a,{flow:"login",mdxType:"RenderFlow"}),Object(o.b)("h2",{id:"login-form-validation"},"Login Form Validation"),Object(o.b)("p",null,"The form payloads are then submitted to ORY Kratos which follows up with:"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},"An HTTP 302 Found redirect pointing to the Login UI for Browser Clients."),Object(o.b)("li",{parentName:"ul"},"An ",Object(o.b)("inlineCode",{parentName:"li"},"application/json")," response for API Clients.")),Object(o.b)("h3",{id:"login-with-usernameemail-and-password-1"},"Login with Username/Email and Password"),Object(o.b)("p",null,"To complete the login, the end-user fills out their identifier (username, email,\nphone number, ...) and the password. Possible validation errors include a\nmissing identifier or password, or invalid credentials:"),Object(o.b)(d.a,{items:u.c,mdxType:"CodeTabs"}),Object(o.b)("p",null,"When validation errors happen, browser clients receive a HTTP 302 Found redirect\nto the Login Flow UI, containing the Login Flow ID which includes the error\npayloads."),Object(o.b)("p",null,"For API Clients, the server typically responds with HTTP 400 Bad Request and the\nLogin Flow in the response payload as JSON."),Object(o.b)("h3",{id:"login-with-google-facebook-github--openid-connect--oauth-20-1"},"Login with Google, Facebook, GitHub, ..., OpenID Connect / OAuth 2.0"),Object(o.b)("p",null,"Completing the ",Object(o.b)("inlineCode",{parentName:"p"},"oidc")," method requires the user to go through an OAuth 2.0 or\nOpenID Connect flow which involves logging into the upstream identity provider\n(e.g. Google) and giving consent."),Object(o.b)("div",{className:"admonition admonition-note alert alert--secondary"},Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-heading"}),Object(o.b)("h5",{parentName:"div"},Object(o.b)("span",Object(a.a)({parentName:"h5"},{className:"admonition-icon"}),Object(o.b)("svg",Object(a.a)({parentName:"span"},{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"16",viewBox:"0 0 14 16"}),Object(o.b)("path",Object(a.a)({parentName:"svg"},{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})))),"note")),Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-content"}),Object(o.b)("p",{parentName:"div"},"If the user has never signed in with the given provider before, a new account\nwill be created. It is also possible to link upstream identities (e.g. Google\nprofile) with an existing ORY Kratos identity."))),Object(o.b)("p",null,"A possible validation error is a missing ID Token:"),Object(o.b)(d.a,{items:u.b,mdxType:"CodeTabs"}),Object(o.b)("h2",{id:"successful-login"},"Successful Login"),Object(o.b)("p",null,"Completing the login behaves differently for Browser and API Clients."),Object(o.b)("h3",{id:"browser-clients"},"Browser Clients"),Object(o.b)("p",null,"When the login is completed successfully, ORY Kratos responds with a HTTP 302\nRedirect to the\n",Object(o.b)("a",Object(a.a)({parentName:"p"},{href:"../../concepts/browser-redirect-flow-completion"}),"configured redirect URL"),".\nAlongside the HTTP 302 Redirect is a ",Object(o.b)("inlineCode",{parentName:"p"},"Set-Cookie")," header which contains the ORY\nKratos Login Session Cookie:"),Object(o.b)("pre",null,Object(o.b)("code",Object(a.a)({parentName:"pre"},{}),"HTTP/1.1 302 Found\nCache-Control: 0\nLocation: http://127.0.0.1:4455/\nSet-Cookie: csrf_token=b8OebRPTPr5ow23mA5gIZmFNLeuMbv8pZz1jT1Ex7ys=; Path=/; Domain=127.0.0.1; Max-Age=31536000; HttpOnly\nSet-Cookie: ory_kratos_session=MTU5OTE2ODc2N3xEdi1CQkFFQ180SUFBUkFCRUFBQVJfLUNBQUVHYzNSeWFXNW5EQThBRFhObGMzTnBiMjVmZEc5clpXNEdjM1J5YVc1bkRDSUFJR055VlROMGRteHhSakJrUzBkbmRUUjBlVFY1V0RCRWFVTnJXVmR6V25oaHx2DICsB6IMbaHSQwnYITUZqr7Qx7CxUlnaneJWH495wQ==; Path=/; Expires=Fri, 04 Sep 2020 21:32:47 GMT; Max-Age=86400; HttpOnly; SameSite=Lax\nVary: Cookie\nDate: Thu, 03 Sep 2020 21:32:47 GMT\nContent-Length: 0\n")),Object(o.b)("p",null,"Now, whenever the browser is making a request (with cookies) to the\n",Object(o.b)("inlineCode",{parentName:"p"},"http://127.0.0.1/sessions/whoami")," endpoint, the session will be returned:"),Object(o.b)("pre",null,Object(o.b)("code",Object(a.a)({parentName:"pre"},{className:"language-shell",metastring:"script",script:!0}),'curl -s -H "Cookie: ory_kratos_session=MTU5OTE2ODc2N3xEdi1CQkFFQ180SUFBUkFCRUFBQVJfLUNBQUVHYzNSeWFXNW5EQThBRFhObGMzTnBiMjVmZEc5clpXNEdjM1J5YVc1bkRDSUFJR055VlROMGRteHhSakJrUzBkbmRUUjBlVFY1V0RCRWFVTnJXVmR6V25oaHx2DICsB6IMbaHSQwnYITUZqr7Qx7CxUlnaneJWH495wQ==" \\\n  http://127.0.0.1:4433/sessions/whoami | jq\n\n{\n  "id": "ede90ce6-2420-435a-a745-3d8ab1a9636c",\n  "active": true,\n  "expires_at": "2020-09-04T21:32:47.5642404Z",\n  "authenticated_at": "2020-09-03T21:32:47.5881038Z",\n  "issued_at": "2020-09-03T21:32:47.5642688Z",\n  "identity": {\n    "id": "d96e86d9-bc33-4aa5-b865-4ade8a3974b3",\n    "schema_id": "default",\n    "schema_url": "http://127.0.0.1:4433/schemas/default",\n    "traits": {\n      "email": "foouser@ory.sh",\n      "name": {\n        "first": "foo",\n        "last": "user"\n      }\n    },\n    "verifiable_addresses": [\n      {\n        "id": "81bbdeae-6333-42f2-877e-26c78acb6ea5",\n        "value": "foouser@ory.sh",\n        "verified": false,\n        "via": "email",\n        "status": "pending",\n        "verified_at": null\n      }\n    ],\n    "recovery_addresses": [\n      {\n        "id": "596c1db4-ccaa-4f4e-9623-cb7e768026ad",\n        "value": "foouser@ory.sh",\n        "via": "email"\n      }\n    ]\n  }\n}\n')),Object(o.b)("h3",{id:"api-clients"},"API Clients"),Object(o.b)("p",null,"For API Clients, ORY Kratos responds with a JSON payload which includes the\nidentity which just authenticated, the session, and the ORY Kratos Session\nToken:"),Object(o.b)("pre",null,Object(o.b)("code",Object(a.a)({parentName:"pre"},{className:"language-shell",metastring:"script",script:!0}),'# Inits a Login Flow\n$ actionUrl=$(\\\n  curl -s -X GET -H "Accept: application/json" \\\n    "http://127.0.0.1:4433/self-service/login/api" \\\n    | jq -r \'.methods.password.config.action\'\\\n)\n\n# Complete Login Flow with password method\n$ curl -s -X POST -H  "Accept: application/json" -H "Content-Type: application/json" \\\n    -d \'{"identifier": "api@user.org", "password": "iohuasf0897zAJHf"}\' \\\n    "$actionUrl" | jq\n\n{\n  "session_token": "oFZzgLpsacUpUy2cvQPtrGa2046WcXCR",\n  "session": {\n    "id": "8f660ce3-69ec-4aeb-9fda-f9230dc3243f",\n    "active": true,\n    "expires_at": "2020-08-25T13:42:15.7411522Z",\n    "authenticated_at": "2020-08-24T13:42:15.7411522Z",\n    "issued_at": "2020-08-24T13:42:15.7412042Z",\n    "identity": {\n      "id": "bf32596a-f853-47c4-91e6-a3f41cf4949d",\n      "schema_id": "default",\n      "schema_url": "http://127.0.0.1:4433/schemas/default",\n      "traits": {\n        "email": "api@user.org",\n        "name": {\n          "last": "User",\n          "first": "API"\n        }\n      },\n      "verifiable_addresses": [\n        {\n          "id": "f877db6c-7dfb-45e3-bbeb-ac8349348128",\n          "value": "api@user.org",\n          "verified": false,\n          "via": "email",\n          "verified_at": null,\n          "expires_at": "2020-08-24T14:35:59.125873Z"\n        }\n      ],\n      "recovery_addresses": [\n        {\n          "id": "065a908c-82be-4110-bf67-9910f36242b7",\n          "value": "api@user.org",\n          "via": "email"\n        }\n      ]\n    }\n  }\n}\n')),Object(o.b)("p",null,"The ORY Kratos Session Token can be checked at the\n",Object(o.b)("inlineCode",{parentName:"p"},"http://127.0.0.1/sessions/whoami")," endpoint:"),Object(o.b)("pre",null,Object(o.b)("code",Object(a.a)({parentName:"pre"},{className:"language-shell",metastring:"script",script:!0}),'$ curl -s -H "Authorization: Bearer svX8bE9HTiVpMr7r55TtKtcOkLRhAq1a" \\\n  http://127.0.0.1:4433/sessions/whoami | jq\n\n{\n  "id": "d09fc470-9e11-4e70-855f-0dc1aee7e501",\n  "active": true,\n  "expires_at": "2020-09-05T10:52:52.1350455Z",\n  "authenticated_at": "2020-09-04T10:52:52.1472702Z",\n  "issued_at": "2020-09-04T10:52:52.1350737Z",\n  "identity": {\n    "id": "9ee8fb81-9d5c-47a7-9cee-28a0f64dccbb",\n    "schema_id": "default",\n    "schema_url": "http://127.0.0.1:4433/schemas/default",\n    "traits": {\n      "email": "api@user.org",\n      "name": {\n        "first": "API",\n        "last": "User"\n      }\n    },\n    "verifiable_addresses": [\n      {\n        "id": "3ba119c6-4e9a-466c-8910-40b238229aa6",\n        "value": "api@user.org",\n        "verified": false,\n        "via": "email",\n        "status": "pending",\n        "verified_at": null\n      }\n    ],\n    "recovery_addresses": [\n      {\n        "id": "9dec10d0-1079-4a5d-b1be-cd15418c640a",\n        "value": "api@user.org",\n        "via": "email"\n      }\n    ]\n  }\n}\n')),Object(o.b)("h2",{id:"refreshing-a-session"},"Refreshing a Session"),Object(o.b)("p",null,"In some cases it is required to refresh a login session. This is the case when\nupdating one's password. Refreshing a session updates the ",Object(o.b)("inlineCode",{parentName:"p"},"authenticated_at"),"\ntime."),Object(o.b)("div",{className:"admonition admonition-info alert alert--info"},Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-heading"}),Object(o.b)("h5",{parentName:"div"},Object(o.b)("span",Object(a.a)({parentName:"h5"},{className:"admonition-icon"}),Object(o.b)("svg",Object(a.a)({parentName:"span"},{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"16",viewBox:"0 0 14 16"}),Object(o.b)("path",Object(a.a)({parentName:"svg"},{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})))),"info")),Object(o.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-content"}),Object(o.b)("p",{parentName:"div"},"Refreshing a session will not log the user out, unless another user signs in."))),Object(o.b)("p",null,"To refresh a session, append ",Object(o.b)("inlineCode",{parentName:"p"},"?refresh=true")," to:"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"/self-service/login/browser")," for browser Clients (e.g.\n",Object(o.b)("inlineCode",{parentName:"li"},"http://127.0.0.1:4433/self-service/login/browser?refresh=true"),")"),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"/self-service/login/api")," for API Clients (e.g.\n",Object(o.b)("inlineCode",{parentName:"li"},"http://127.0.0.1:4433/self-service/login/api?refresh=true"),")")),Object(o.b)("h2",{id:"hooks"},"Hooks"),Object(o.b)("p",null,"ORY Kratos allows you to configure hooks that run before and after a Login Flow.\nThis may be helpful if you'd like to restrict logins to IPs coming from your\ninternal network or other logic."),Object(o.b)("p",null,"For more information about hooks please read the ",Object(o.b)("a",Object(a.a)({parentName:"p"},{href:"../hooks"}),"Hook Documentation"),"."))}g.isMDXComponent=!0},443:function(e,n,t){"use strict";var a=t(0),i=t.n(a),o=t(459),r=t.n(o),s=t(54),l=t.n(s),c=t(456),d=t.n(c);r.a.initialize({startOnLoad:!0,logLevel:"fatal",securityLevel:"strict",arrowMarkerAbsolute:!1,theme:"neutral",flowchart:{useMaxWidth:!0,htmlLabels:!0,rankSpacing:65,nodeSpacing:30,curve:"basis"},sequence:{useMaxWidth:!0},gantt:{useMaxWidth:!0}});n.a=function(e){var n,t=e.chart,o=Object(a.useState)(!1),s=o[0],c=o[1],u=Object(a.useState)(void 0),b=u[0],p=u[1],f=Object(a.useState)("mermaid-"+Math.random().toString(36).substr(2,-1))[0],m=function(){return c(!s)};return Object(a.useEffect)((function(){r.a.render(f,t,(function(e){p(e)}))}),[]),i.a.createElement(i.a.Fragment,null,i.a.createElement("div",{onClick:m,className:d()(l.a.graph,l.a.pointer),dangerouslySetInnerHTML:{__html:b}}),i.a.createElement("div",{onClick:m,className:d()(l.a.overlay,l.a.pointer,l.a.graph,(n={},n[l.a.visible]=s,n))},i.a.createElement("div",{onClick:function(e){return e.stopPropagation()},className:d()(l.a.backdrop,l.a.graph),dangerouslySetInnerHTML:{__html:b}})))}},447:function(e,n,t){"use strict";var a=t(0),i=t.n(a),o=t(451),r=t(446),s=t(55),l=t.n(s),c=37,d=39;n.a=function(e){var n=e.lazy,t=e.block,s=e.defaultValue,u=e.values,b=e.groupId,p=e.className,f=Object(o.a)(),m=f.tabGroupChoices,h=f.setTabGroupChoices,g=Object(a.useState)(s),w=g[0],v=g[1],O=a.Children.toArray(e.children);if(null!=b){var j=m[b];null!=j&&j!==w&&u.some((function(e){return e.value===j}))&&v(j)}var y=function(e){v(e),null!=b&&h(b,e)},N=[];return i.a.createElement("div",null,i.a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:Object(r.a)("tabs",{"tabs--block":t},p)},u.map((function(e){var n=e.value,t=e.label;return i.a.createElement("li",{role:"tab",tabIndex:0,"aria-selected":w===n,className:Object(r.a)("tabs__item",l.a.tabItem,{"tabs__item--active":w===n}),key:n,ref:function(e){return N.push(e)},onKeyDown:function(e){!function(e,n,t){switch(t.keyCode){case d:!function(e,n){var t=e.indexOf(n)+1;e[t]?e[t].focus():e[0].focus()}(e,n);break;case c:!function(e,n){var t=e.indexOf(n)-1;e[t]?e[t].focus():e[e.length-1].focus()}(e,n)}}(N,e.target,e)},onFocus:function(){return y(n)},onClick:function(){y(n)}},t)}))),n?Object(a.cloneElement)(O.filter((function(e){return e.props.value===w}))[0],{className:"margin-vert--md"}):i.a.createElement("div",{className:"margin-vert--md"},O.map((function(e,n){return Object(a.cloneElement)(e,{key:n,hidden:e.props.value!==w})}))))}},448:function(e,n,t){"use strict";var a=t(3),i=t(0),o=t.n(i);n.a=function(e){var n=e.children,t=e.hidden,i=e.className;return o.a.createElement("div",Object(a.a)({role:"tabpanel"},{hidden:t,className:i}),n)}},451:function(e,n,t){"use strict";var a=t(0),i=t(452);n.a=function(){var e=Object(a.useContext)(i.a);if(null==e)throw new Error("`useUserPreferencesContext` is used outside of `Layout` Component.");return e}},452:function(e,n,t){"use strict";var a=t(0),i=Object(a.createContext)(void 0);n.a=i},457:function(e,n,t){"use strict";var a=t(0),i=t.n(a),o=t(478),r=t.n(o),s=t(458),l=t(56),c=t.n(l),d=function(e,n){if(!e)return 0;var t=n.findIndex((function(n){return n.indexOf(e)>-1}));return-1===t?0:t};n.a=function(e){var n=e.src,t=Object(a.useState)(""),o=t[0],l=t[1];Object(a.useEffect)((function(){var t,a,i;r()(n.replace("github.com","raw.githubusercontent.com").replace("/blob/","/")).then((function(e){return e.text()})).then((t=e,a=t.startAt,i=t.endAt,function(e){var n=e.split("\n"),t=d(a,n);t>0&&(n=["// ..."].concat(n.slice(t,-1)));var o=d(i,n);return o>0&&(n=[].concat(n.slice(0,o+1),["// ..."])),n.join("\n")})).then(l).catch(console.error)}),[]);var u="language-"+function(e){var n=e.split(".").pop();switch(n){case"jsx":return"jsx";case"tsx":return"tsx";case"ts":return"typescript";case"go":return"go";case"yaml":case"yml":return"yaml";case"js":return"javascript";case"html":return"html";case"pug":return"pug";default:return n}}(n),b='title="'+function(e){var n=e.match(new RegExp("https://github.com/[^/]+/[^/]+/blob/[^/]+/(.+)","i"))||[];return n.length>=2?n[1]:e}(n)+'"';return i.a.createElement("div",{className:c.a.container},i.a.createElement(s.a,{metastring:b,className:u,children:o}))}},460:function(e,n){},461:function(e,n){},462:function(e,n){},463:function(e,n){},464:function(e,n){},465:function(e,n){},466:function(e,n){},467:function(e,n){},468:function(e,n){},469:function(e,n){},470:function(e,n){},471:function(e,n){},473:function(e,n,t){var a={"./locale":449,"./locale.js":449};function i(e){var n=o(e);return t(n)}function o(e){if(!t.o(a,e)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return a[e]}i.keys=function(){return Object.keys(a)},i.resolve=o,e.exports=i,i.id=473},474:function(e,n,t){"use strict";var a=t(0),i=t.n(a);n.a=function(){return i.a.createElement("div",{className:"admonition admonition-warning alert alert--danger"},i.a.createElement("div",{className:"admonition-heading"},i.a.createElement("h5",null,i.a.createElement("span",{className:"admonition-icon"},i.a.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"16",viewBox:"0 0 12 16"},i.a.createElement("path",{"fill-rule":"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"}))),"warning")),i.a.createElement("div",{className:"admonition-content"},i.a.createElement("p",null,"Never use API flows to implement Browser applications!"),i.a.createElement("p",null,"Using API flows in Single-Page-Apps as well as server-side apps opens up several potential attack vectors, including Login and other CSRF attacks.")))}},475:function(e,n,t){"use strict";var a=t(0),i=t.n(a),o=t(443);n.a=function(e){return i.a.createElement(i.a.Fragment,null,i.a.createElement(o.a,{chart:(n=e,t=n.flows,a=void 0===t?["login","registration","settings","..."]:t,r=n.interactions,s=void 0===r?['"Log in"','"Sign Up"','"Update Email"',"..."]:r,l=n.success,c=void 0===l?"Perform flow-specific action (e.g. create user, set session cookie, ...)":l,d=a.length>1?"<"+a.join("|")+">":""+a.join("|"),"\nsequenceDiagram\n\n  participant B as Browser\n  participant K as ORY Kratos\n  participant A as Flow UI\n\n  B->>K: Follow link to /self-service/"+d+"/browser\n  K--\x3e>K: Create and store new "+a.join(", ")+" flow\n  K->>B: HTTP 302 Found <selfservice.flows."+d+".ui_url>?flow=<flow-id>\n\n  B->>A: Opens <selfservice.flows.<"+a.join("|")+">.ui_url>?flow=<flow-id>\n  A--\x3e>K: Fetches data to render forms using /selfservice/"+d+"/flows?id=<flow-id>\n  B--\x3e>A: Fills out forms, clicks e.g. "+s.join(", ")+"\n  B->>K: Submits form\n  K--\x3e>K: Validates and processes form payloads\n\n  alt Form payload is valid\n    K->>B: "+c+"\n  else Form payload invalid\n    K--\x3e>K: Update and store flow (e.g. add form validation errors)\n    K--\x3e>B: HTTP 302 Found <selfservice.flows."+d+".ui_url>?flow=<flow-id>\n    B->>A: Opens <selfservice.flows."+d+"?flow=<flow-id>\n    A--\x3e>K: Fetches data to render form fields and errors\n    B->>K: Repeat flow with input data, submit, validate, ...\n  end\n")}),i.a.createElement("p",null,"The ",i.a.createElement("em",null,"Flow UI")," (",i.a.createElement("strong",null,"your application!"),') is responsible for rendering the actual Login and Registration HTML Forms. You can of course implement one app for rendering all the Login, Registration, ... screens, and another app (think "Service Oriented Architecture", "Micro-Services" or "Service Mesh") is responsible for rendering your Dashboards, Management Screens, and so on.'));var n,t,a,r,s,l,c,d}},476:function(e,n,t){"use strict";var a=t(0),i=t.n(a),o=t(443);n.a=function(e){return i.a.createElement(o.a,{chart:(n=e,t=n.flows,a=void 0===t?["login","registration","settings","..."]:t,r=n.methods,s=void 0===r?["password","oidc","..."]:r,l=n.interactions,c=void 0===l?['"Log in"','"Sign Up"','"Update Email"',"..."]:l,d=n.success,u=void 0===d?"Perform flow-specific action (e.g. create user, set session cookie, ...)":d,b=a.length>1?"<"+a.join("|")+">":""+a.join("|"),"\nsequenceDiagram\n  participant B as API Client\n  participant K as ORY Kratos\n\n  B->>K: REST GET /self-service/"+b+"/api\n  K--\x3e>K: Create and store new "+a.join(", ")+" flow\n  K->>B: HTTP 200 OK with flow as application/json payload\n  B--\x3e>B: Render form using e.g. Native iOS UI Elements\n  B--\x3e>B: User fills out forms, clicks e.g. "+c+"\n  B->>K: REST POST to e.g. /self-service/"+b+"/methods/<"+s.join("|")+">\n  K--\x3e>K: Validates and processes payload\n  alt Form payload is valid\n    K->>B: "+u+"\n  else Form payload invalid\n    K--\x3e>K: Update and store flow (e.g. add form validation errors)\n    K->>B: Respond with e.g. HTTP 400 Bad Request and updated flow as payload\n    B--\x3e>B: Render form and validation errors using e.g. Native iOS UI Elements\n    B--\x3e>K: Repeat flow with input data, submit, validate, ...\n  end\n")});var n,t,a,r,s,l,c,d,u,b}},477:function(e,n,t){"use strict";var a=t(447),i=t(448),o=t(0),r=t.n(o),s=t(458);n.a=function(e){var n=e.items;return r.a.createElement(a.a,{defaultValue:Object.keys(n)[0],values:Object.keys(n).map((function(e){return{label:n[e].label,value:e}}))},Object.keys(n).map((function(e){return r.a.createElement(i.a,{key:e,value:e},n[e].code?r.a.createElement(s.a,{className:"language-"+n[e].language,children:n[e].code}):r.a.createElement("img",{src:n[e].image,alt:n[e].alt}))})))}},478:function(e,n,t){"use strict";var a=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==a)return a;throw new Error("unable to locate global object")}();e.exports=n=a.fetch,a.fetch&&(n.default=a.fetch.bind(a)),n.Headers=a.Headers,n.Request=a.Request,n.Response=a.Response},481:function(e,n,t){"use strict";var a=t(447),i=t(448),o=t(0),r=t.n(o),s=t(457),l=t.p+"assets/images/browser-61597c2d37644d2e9a6cd62143a17d19.png",c=t.p+"assets/images/browser-3fffa4ddf3b8dbaa9171845af0b1ace3.png",d=t.p+"assets/images/browser-95c5fd81e495c104256cf0460ebd835a.png",u=t.p+"assets/images/browser-22673e53b8fd2d5b86732105f965b818.png";n.a=function(e){var n,t,o=e.flow;switch(o){case"registration":n=r.a.createElement("img",{src:d,alt:"User Registration HTML Form"});break;case"login":n=r.a.createElement("img",{src:l,alt:"User Login HTML Form"});break;case"settings":n=r.a.createElement("img",{src:c,alt:"Profile Settings HTML Form"});break;case"recovery":n=r.a.createElement("img",{src:u,alt:"Account Recovery HTML Form"});break;case"verification":n=r.a.createElement("img",{src:u,alt:"Email Verification HTML Form"})}return r.a.createElement(a.a,{defaultValue:"browser",values:[{label:"Browser UI",value:"browser"},{label:"ExpressJS & Handlebars",value:"express"},{label:"ReactJS",value:"react"},{label:"React Native",value:"react-native"}]},r.a.createElement(i.a,{value:"browser"},n),r.a.createElement(i.a,{value:"express"},r.a.createElement(s.a,{lang:"js",link:"https://github.com/ory/kratos-selfservice-ui-node/blob/master/src/routes/"+o+".ts",src:"https://raw.githubusercontent.com/ory/kratos-selfservice-ui-node/master/src/routes/"+o+".ts"}),"The views can be rather simple, as ORY Kratos provides you with all the information you need for rendering the forms. The following examples use Handlebars and a generic form generator to render the Flow:",r.a.createElement(a.a,{defaultValue:"view",values:[{label:(t=o,t.charAt(0).toUpperCase()+t.slice(1)+" View"),value:"view"},{label:"Generic Form View",value:"generic-form"},{label:"Example Input Form Element",value:"input-form"}]},r.a.createElement(i.a,{value:"view"},r.a.createElement(s.a,{lang:"handlebars",link:"https://github.com/ory/kratos-selfservice-ui-node/blob/master/views/"+o+".hbs",src:"https://raw.githubusercontent.com/ory/kratos-selfservice-ui-node/master/views/"+o+".hbs"})),r.a.createElement(i.a,{value:"generic-form"},r.a.createElement(s.a,{lang:"handlebars",link:"https://github.com/ory/kratos-selfservice-ui-node/blob/master/views/partials/form.hbs",src:"https://raw.githubusercontent.com/ory/kratos-selfservice-ui-node/master/views/partials/form.hbs"})),r.a.createElement(i.a,{value:"input-form"},r.a.createElement(s.a,{lang:"handlebars",link:"https://github.com/ory/kratos-selfservice-ui-node/blob/master/views/partials/form_input_default.hbs",src:"https://raw.githubusercontent.com/ory/kratos-selfservice-ui-node/master/views/partials/form_input_default.hbs"}))),"The rest of the form partials can be found"," ",r.a.createElement("a",{href:"https://github.com/ory/kratos-selfservice-ui-node/tree/master/views/partials"},"here"),"."),r.a.createElement(i.a,{value:"react"},"A React example is currently in the making."),r.a.createElement(i.a,{value:"react-native"},"A React Native example is currently in the making."))}},631:function(e,n,t){"use strict";t.d(n,"e",(function(){return a})),t.d(n,"a",(function(){return i})),t.d(n,"d",(function(){return o})),t.d(n,"c",(function(){return r})),t.d(n,"b",(function(){return s}));var a={curl:{label:"Raw HTTP",language:"shell",code:t(632).default},html:{label:"HTML",language:"html",code:t(633).default},jsx:{label:"ReactJS",language:"js",code:t(634).default},node:{label:"Angular",language:"html",code:t(635).default},angular:{label:"ExpressJS",language:"js",code:t(636).default}},i={curl:{label:"Raw HTTP",language:"shell",code:t(637).default},js:{label:"JavaScript SDK",language:"js",code:t(638).default},go:{label:"Go SDK",language:"go",code:t(639).default}},o={curl:{label:"Raw HTTP",language:"shell",code:t(640).default},js:{label:"Node",language:"js",code:t(641).default},go:{label:"Go",language:"go",code:t(642).default}},r={browser:{label:"Browser UI",image:t(643).default,alt:"User Login HTML Form with validation errors"},missing:{label:"Missing Email",language:"shell",code:t(644).default},wrong:{label:"Wrong Credentials",language:"shell",code:t(645).default}},s={missing:{label:"Missing ID Token",language:"shell",code:t(646).default}}},632:function(e,n,t){"use strict";t.r(n),n.default='curl -s -v -X GET \\\n  -H "Accept: text/html"  \\\n  http://127.0.0.1:4433/self-service/login/browser\n\n> GET /self-service/login/browser HTTP/1.1\n> Host: 127.0.0.1:4433\n> User-Agent: curl/7.64.1\n> Accept: text/html\n>\n< HTTP/1.1 302 Found\n< Cache-Control: 0\n< Content-Type: text/html; charset=utf-8\n< Location: http://127.0.0.1:4455/auth/login?flow=df607aa1-d555-4b2a-b3e4-0f5a1d2fe6f3\n< Set-Cookie: csrf_token=y4Ocu6V83BapwJwbPw/pnlRHHw40DZbjq5iuDrxl0Ds=; Path=/; Domain=127.0.0.1; Max-Age=31536000; HttpOnly\n<\n<a href="http://127.0.0.1:4455/auth/login?flow=df607aa1-d555-4b2a-b3e4-0f5a1d2fe6f3">Found</a>.\n'},633:function(e,n,t){"use strict";t.r(n),n.default='<a href="http://127.0.0.1:4433/self-service/login/browser">Log in</a>\n\n\x3c!-- or --\x3e\n\n<script>\n  const initLogin = () => {\n    window.location.href = \'http://127.0.0.1:4433/self-service/login/browser\'\n  }\n<\/script>\n\n<a onClick="initLogin">Sign in</a>\n'},634:function(e,n,t){"use strict";t.r(n),n.default="import React from 'react'\n\nconst MyComponent = () => (\n  <a href=\"http://127.0.0.1:4433/self-service/login/browser\">Sign in</a>\n)\n"},635:function(e,n,t){"use strict";t.r(n),n.default="express.get('/login', function (req, res) {\n  res.redirect(302, 'http://127.0.0.1:4433/self-service/login/browser')\n})\n"},636:function(e,n,t){"use strict";t.r(n),n.default='<a href="http://127.0.0.1:4433/self-service/login/browser">Log in</a>\n'},637:function(e,n,t){"use strict";t.r(n),n.default='$ curl -H "Accept: application/json" -s\n  \'http://127.0.0.1:4434/self-service/login/flows?id=7c4260f5-55ad-470a-b1d4-e72dd011e4fe\' | jq\n\n{\n  "id": "7c4260f5-55ad-470a-b1d4-e72dd011e4fe",\n  "type": "browser",\n  "expires_at": "2020-08-24T12:01:46.0750749Z",\n  "issued_at": "2020-08-24T11:51:46.0750749Z",\n  "request_url": "http://127.0.0.1:4433/self-service/login/browser",\n  "active": "password",\n  "methods": {\n    // password ...\n    // oidc ...\n  },\n  "forced": false\n}\n'},638:function(e,n,t){"use strict";t.r(n),n.default="import { Configuration, PublicApi } from '@ory/kratos-client';\nconst kratos = new PublicApi(new Configuration({ basePath: 'http://127.0.0.1:4433/' }));\n\nconst flowId = '' // usually something like: req.query.flow\n\nreturn kratos.getSelfServiceLoginFlow(flowId)\n  .then(({ status, data: flow, ...response }) => {\n    console.log(flow) // see the Raw HTTP tab for the payload\n  })\n"},639:function(e,n,t){"use strict";t.r(n),n.default='package samples\n\nimport (\n  "fmt"\n\n  "github.com/ory/kratos-client-go/client/public"\n  "github.com/ory/kratos-client-go/client"\n)\n\nfunc main() {\n  c := client.NewHTTPClientWithConfig(nil,\n    &client.TransportConfig{Host: "127.0.0.1:4433", BasePath: "/", Schemes: []string{"http"}})\n\n  flowID := "" // Usually something like: res.Request.URL.Query().Get("flow")\n\n  rs, err := c.Public.GetSelfServiceLoginFlow(\n    public.NewGetSelfServiceLoginFlowParams().\n      WithID(flowID),\n  )\n\n  fmt.Printf("%+v", rs.Payload) //\n}\n'},640:function(e,n,t){"use strict";t.r(n),n.default='$ curl -s -X GET \\\n  -H "Accept: application/json"  \\\n  http://127.0.0.1:4433/self-service/login/api | jq\n\n{\n  "id": "6bb7f2a2-a2f2-44cd-9d14-ee7ca876d60b",\n  "type": "api",\n  "expires_at": "2020-09-03T20:04:57.37098805Z",\n  "issued_at": "2020-09-03T19:54:57.37098805Z",\n  "request_url": "http://127.0.0.1:4433/self-service/login/api",\n  "methods": {\n    // password,\n    // oidc,\n    // ...\n  },\n  "forced": false\n}\n'},641:function(e,n,t){"use strict";t.r(n),n.default="import { Configuration, PublicApi } from '@ory/kratos-client';\nconst kratos = new PublicApi(new Configuration({ basePath: 'http://127.0.0.1:4433/' }));\n\nkratos.initializeSelfServiceLoginViaAPIFlow()\n  .then(({ status, data: flow }) => {\n    console.log(flow) // see the Raw HTTP tab for the payload\n  })\n"},642:function(e,n,t){"use strict";t.r(n),n.default='package api\n\nimport (\n  "fmt"\n\n  "github.com/ory/kratos-client-go/client/public"\n  "github.com/ory/kratos-client-go/client"\n)\n\nfunc main() {\n  c := client.NewHTTPClientWithConfig(nil,\n    &client.TransportConfig{Host: "127.0.0.1:4433", BasePath: "/", Schemes: []string{"http"}})\n\n  rs, _ := c.Public.InitializeSelfServiceLoginViaAPIFlow(public.\n    NewInitializeSelfServiceLoginViaAPIFlowParams())\n\n  fmt.Printf("%+v", rs.Payload)\n}\n'},643:function(e,n,t){"use strict";t.r(n),n.default=t.p+"assets/images/browser-error-b6509d4065a4bfb5ab01e37a0389a65f.png"},644:function(e,n,t){"use strict";t.r(n),n.default='$ curl -H "Accept: application/json" -s \\\n  \'http://127.0.0.1:4433/self-service/login/flows?id=2e41015e-3b05-4e6a-8bc5-cdecf808d52e\' \\\n  | jq -r \'.methods.password.config\'\n\n{\n  "action": "http://127.0.0.1:4433/self-service/login/methods/password?flow=2e41015e-3b05-4e6a-8bc5-cdecf808d52e",\n  "method": "POST",\n  "fields": [\n    {\n      "name": "identifier",\n      "type": "text",\n      "required": true,\n      "value": "foo@ory.sh"\n    },\n    {\n      "name": "password",\n      "type": "password",\n      "required": true,\n      "messages": [\n        {\n          "id": 4000001,\n          "text": "length must be >= 1, but got 0",\n          "type": "error"\n        }\n      ]\n    },\n    {\n      "name": "csrf_token",\n      "type": "hidden",\n      "required": true,\n      "value": "iOINjfSS6WycVC9sDCzMgK0dGUCyBfTTwRyKUz4DoSI62z0AYmd+ckzRVZsMZ6gzG/xJd359tJHibOKkDM2Lcw=="\n    }\n  ]\n}\n'},645:function(e,n,t){"use strict";t.r(n),n.default='$ curl -H "Accept: application/json" -s \\\n  \'http://127.0.0.1:4433/self-service/login/flows?id=4d1c07e0-4062-4609-a9fe-51b67bb0229c\' \\\n  | jq -r \'.methods.password.config\'\n\n{\n  "action": "http://127.0.0.1:4433/self-service/login/methods/password?flow=4d1c07e0-4062-4609-a9fe-51b67bb0229c",\n  "method": "POST",\n  "fields": [\n    {\n      "name": "identifier",\n      "type": "text",\n      "required": true,\n      "value": "idonotexist@ory.sh"\n    },\n    {\n      "name": "password",\n      "type": "password",\n      "required": true\n    },\n    {\n      "name": "csrf_token",\n      "type": "hidden",\n      "required": true,\n      "value": "+PvwKv2leJuBleZXkHwZHCgwybgu8eTazjCAV0OezmPCMtk5XjAk5vAyOdNn1ZHavl/2ksGDFN0/oD7D6KUdfg=="\n    }\n  ],\n  "messages": [\n    {\n      "id": 4000006,\n      "text": "The provided credentials are invalid, check for spelling mistakes in your password or username, email address, or phone number.",\n      "type": "error",\n      "context": {}\n    }\n  ]\n}\n'},646:function(e,n,t){"use strict";t.r(n),n.default='$ curl -s -H "Accept: application/json" \\\n  \'http://127.0.0.1:4433/self-service/login/flows?id=2e87577f-1209-407c-b523-4727d7bbdbd4\' \\\n  | jq -r \'methods.oidc.config\'\n\n{\n  "action": "http://127.0.0.1:4433/self-service/methods/oidc/auth/2e87577f-1209-407c-b523-4727d7bbdbd4",\n  "method": "POST",\n  "messages": [\n    {\n      "id": 4000000,\n      "type": "error",\n      "text": "Authentication failed because no id_token was returned. Please accept the \\"openid\\" permission and try again."\n    }\n  ],\n  "fields": [\n    {\n      "name": "csrf_token",\n      "type": "hidden",\n      "required": true,\n      "value": "O0e8KWxx1zZeNEgUOxNFvV8dVMrK63MXoxU102lj9n0nXcsaDWXhPn0TiZG3Nk+nLi/pT1wjTUsHniLRKOpp3w=="\n    },\n    {\n      "name": "provider",\n      "type": "submit",\n      "value": "github"\n    }\n  ]\n}\n'}}]);