text: (window.webpackJsonp=window.webpackJsonp||[]).push([[90],{225:function(e,t,i){"use strict";i.r(t),i.d(t,"frontMatter",(function(){return o})),i.d(t,"metadata",(function(){return s})),i.d(t,"rightToc",(function(){return l})),i.d(t,"default",(function(){return b}));var n=i(2),a=i(9),r=(i(0),i(324)),o={id:"user-login-user-registration",title:"User Login and User Registration"},s={id:"version-v0.1/self-service/flows/user-login-user-registration",title:"User Login and User Registration",description:"ORY Kratos supports two type of login and registration flows:",source:"@site/versioned_docs/version-v0.1/self-service/flows/user-login-user-registration.md",permalink:"/kratos/docs/v0.1/self-service/flows/user-login-user-registration",editUrl:"https://github.com/ory/kratos/edit/master/docs/versioned_docs/version-v0.1/self-service/flows/user-login-user-registration.md",version:"v0.1",lastUpdatedBy:"hackerman",lastUpdatedAt:1586177162,sidebar:"version-v0.1/docs",previous:{title:"Overview",permalink:"/kratos/docs/v0.1/self-service/flows/index"},next:{title:"User Logout",permalink:"/kratos/docs/v0.1/self-service/flows/user-logout"}},l=[{value:"Self-Service User Login and User Registration for Browser Applications",id:"self-service-user-login-and-user-registration-for-browser-applications",children:[{value:"The Login and Registration User Interface",id:"the-login-and-registration-user-interface",children:[]},{value:"Code",id:"code",children:[]},{value:"Server-Side Browser Applications",id:"server-side-browser-applications",children:[]},{value:"Client-Side Browser Applications",id:"client-side-browser-applications",children:[]}]},{value:"Self-Service User Login and User Registration for API Clients",id:"self-service-user-login-and-user-registration-for-api-clients",children:[]},{value:"Executing Jobs before User Login",id:"executing-jobs-before-user-login",children:[]},{value:"Executing Jobs after User Login",id:"executing-jobs-after-user-login",children:[]},{value:"Executing Jobs before User Registration",id:"executing-jobs-before-user-registration",children:[]},{value:"Executing Jobs after User Registration",id:"executing-jobs-after-user-registration",children:[]}],c={rightToc:l};function b(e){var t=e.components,i=Object(a.a)(e,["components"]);return Object(r.b)("wrapper",Object(n.a)({},c,i,{components:t,mdxType:"MDXLayout"}),Object(r.b)("p",null,"ORY Kratos supports two type of login and registration flows:"),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"Browser-based (easy): This flow works for all applications running on top of a\nbrowser. Websites, single-page apps, Cordova/Ionic, and so on."),Object(r.b)("li",{parentName:"ul"},"API-based (advanced): This flow works for native applications like iOS\n(Swift), Android (Java), Microsoft (.NET), React Native, Electron, and others.")),Object(r.b)("h2",{id:"self-service-user-login-and-user-registration-for-browser-applications"},"Self-Service User Login and User Registration for Browser Applications"),Object(r.b)("p",null,"ORY Kratos supports browser applications that run on server-side (e.g. Java,\nNodeJS, PHP) as well as client-side (e.g. JQuery, ReactJS, AngularJS, ...)."),Object(r.b)("p",null,"Browser-based login and registration makes use of three core HTTP technologies:"),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"HTTP Redirects"),Object(r.b)("li",{parentName:"ul"},"HTTP POST (",Object(r.b)("inlineCode",{parentName:"li"},"application/json"),", ",Object(r.b)("inlineCode",{parentName:"li"},"application/x-www-urlencoded"),") and RESTful GET\nrequests."),Object(r.b)("li",{parentName:"ul"},"HTTP Cookies to prevent CSRF and Session Hijaking attack vectors.")),Object(r.b)("p",null,"The browser flow is the easiest and most secure to set up and integrated with.\nORY Kratos takes care of all required session and CSRF cookies and ensures that\nall security requirements are fulfilled."),Object(r.b)("p",null,"Future versions of ORY Kratos will be able to deal with multi-domain\nenvironments that require SSO. For example, one account would be used to sign\ninto both ",Object(r.b)("inlineCode",{parentName:"p"},"mydomain.com")," and ",Object(r.b)("inlineCode",{parentName:"p"},"anotherdomain.org"),". A common real-world example is\nusing your Google account to seamlessly be signed into YouTube and Google at the\nsame time."),Object(r.b)("p",null,"This flow is not suitable for scenarios where you use purely programmatic\nclients that do not work well with HTTP Cookies and HTTP Redirects."),Object(r.b)("h3",{id:"the-login-and-registration-user-interface"},"The Login and Registration User Interface"),Object(r.b)("p",null,"In Browser Applications, the User Interface is typically rendered as an HTML\nForm:"),Object(r.b)("pre",null,Object(r.b)("code",Object(n.a)({parentName:"pre"},{className:"language-html"}),'\x3c!-- Login --\x3e\n<form action="..." method="POST">\n  <input type="text" name="identifier" placeholder="Enter your username" />\n  <input type="password" name="password" placeholder="Enter your password" />\n  <input type="hidden" name="csrf_token" value="cdef..." />\n  <input type="submit" />\n</form>\n\n\x3c!-- Registration --\x3e\n<form action="..." method="POST">\n  <input type="email" name="email" placeholder="Enter your E-Mail Address" />\n  <input type="password" name="password" placeholder="Enter your password" />\n  <input\n    type="first_name"\n    name="password"\n    placeholder="Enter your First Name"\n  />\n  <input type="last_name" name="password" placeholder="Enter your Last Name" />\n  <input type="hidden" name="csrf_token" value="cdef..." />\n  <input type="submit" />\n</form>\n')),Object(r.b)("p",null,'Depending on the type of login flows you want to support, this might also be a\n"Sign up/in with GitHub" flow:'),Object(r.b)("pre",null,Object(r.b)("code",Object(n.a)({parentName:"pre"},{className:"language-html"}),'\x3c!-- Login and Registration --\x3e\n<form action="..." method="POST">\n  <input type="hidden" name="csrf_token" value="cdef..." />\n\n  \x3c!-- Basically <a href="https://github.com/login/oauth/authorize?...">Sign up/in with GitHub</a> --\x3e\n  <input type="submit" name="provider" value="GitHub" />\n</form>\n')),Object(r.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(r.b)("p",null,"Each Login and Registration Strategy (e.g.\n",Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"/kratos/docs/v0.1/self-service/strategies/username-email-password"}),"Username and Password"),",\n",Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"/kratos/docs/v0.1/self-service/strategies/openid-connect-social-sign-in-oauth2"}),"Social Sign In"),",\nPasswordless, ...) works a bit differently but they all boil down to the same\nabstract sequence:"),Object(r.b)("p",null,Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gIHBhcnRpY2lwYW50IEIgYXMgQnJvd3NlclxuICBwYXJ0aWNpcGFudCBLIGFzIE9SWSBLcmF0b3NcbiAgcGFydGljaXBhbnQgQSBhcyBZb3VyIEFwcGxpY2F0aW9uXG5cblxuICBCLT4-SzogSW5pdGlhdGUgTG9naW5cbiAgSy0-PkI6IFJlZGlyZWN0cyB0byB5b3VyIEFwcGxpY2F0aW9uJ3MgL2xvZ2luIGVuZHBvaW50XG4gIEItPj5BOiBDYWxscyAvbG9naW5cbiAgQS0tPj5LOiBGZXRjaGVzIGRhdGEgdG8gcmVuZGVyIGZvcm1zIGV0Y1xuICBCLS0-PkE6IEZpbGxzIG91dCBmb3JtcywgY2xpY2tzIGUuZy4gXCJTdWJtaXQgTG9naW5cIlxuICBCLT4-SzogUE9TVHMgZGF0YSB0b1xuICBLLS0-Pks6IFByb2Nlc3NlcyBMb2dpbiBJbmZvXG5cbiAgYWx0IExvZ2luIGRhdGEgdmFsaWRcbiAgICBLLS0-PkI6IFNldHMgc2Vzc2lvbiBjb29raWVcbiAgICBLLT4-QjogUmVkaXJlY3RzIHRvIGUuZy4gRGFzaGJvYXJkXG4gIGVsc2UgTG9naW4gZGF0YSBpbnZhbGlkXG4gICAgSy0tPj5COiBSZWRpcmVjdHMgdG8geW91ciBBcHBsaWNhaXRvbidzIC9sb2dpbiBlbmRwb2ludFxuICAgIEItPj5BOiBDYWxscyAvbG9naW5cbiAgICBBLS0-Pks6IEZldGNoZXMgZGF0YSB0byByZW5kZXIgZm9ybSBmaWVsZHMgYW5kIGVycm9yc1xuICAgIEItLT4-QTogRmlsbHMgb3V0IGZvcm1zIGFnYWluLCBjb3JyZWN0cyBlcnJvcnNcbiAgICBCLT4-SzogUE9TVHMgZGF0YSBhZ2FpbiAtIGFuZCBzbyBvbi4uLlxuICBlbmRcbiIsIm1lcm1haWQiOnsidGhlbWUiOiJuZXV0cmFsIiwic2VxdWVuY2VEaWFncmFtIjp7ImRpYWdyYW1NYXJnaW5YIjoxNSwiZGlhZ3JhbU1hcmdpblkiOjE1LCJib3hUZXh0TWFyZ2luIjowLCJub3RlTWFyZ2luIjoxNSwibWVzc2FnZU1hcmdpbiI6NDUsIm1pcnJvckFjdG9ycyI6dHJ1ZX19fQ"}),Object(r.b)("img",Object(n.a)({parentName:"a"},{src:"https://mermaid.ink/img/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gIHBhcnRpY2lwYW50IEIgYXMgQnJvd3NlclxuICBwYXJ0aWNpcGFudCBLIGFzIE9SWSBLcmF0b3NcbiAgcGFydGljaXBhbnQgQSBhcyBZb3VyIEFwcGxpY2F0aW9uXG5cblxuICBCLT4-SzogSW5pdGlhdGUgTG9naW5cbiAgSy0-PkI6IFJlZGlyZWN0cyB0byB5b3VyIEFwcGxpY2F0aW9uJ3MgL2xvZ2luIGVuZHBvaW50XG4gIEItPj5BOiBDYWxscyAvbG9naW5cbiAgQS0tPj5LOiBGZXRjaGVzIGRhdGEgdG8gcmVuZGVyIGZvcm1zIGV0Y1xuICBCLS0-PkE6IEZpbGxzIG91dCBmb3JtcywgY2xpY2tzIGUuZy4gXCJTdWJtaXQgTG9naW5cIlxuICBCLT4-SzogUE9TVHMgZGF0YSB0b1xuICBLLS0-Pks6IFByb2Nlc3NlcyBMb2dpbiBJbmZvXG5cbiAgYWx0IExvZ2luIGRhdGEgdmFsaWRcbiAgICBLLS0-PkI6IFNldHMgc2Vzc2lvbiBjb29raWVcbiAgICBLLT4-QjogUmVkaXJlY3RzIHRvIGUuZy4gRGFzaGJvYXJkXG4gIGVsc2UgTG9naW4gZGF0YSBpbnZhbGlkXG4gICAgSy0tPj5COiBSZWRpcmVjdHMgdG8geW91ciBBcHBsaWNhaXRvbidzIC9sb2dpbiBlbmRwb2ludFxuICAgIEItPj5BOiBDYWxscyAvbG9naW5cbiAgICBBLS0-Pks6IEZldGNoZXMgZGF0YSB0byByZW5kZXIgZm9ybSBmaWVsZHMgYW5kIGVycm9yc1xuICAgIEItLT4-QTogRmlsbHMgb3V0IGZvcm1zIGFnYWluLCBjb3JyZWN0cyBlcnJvcnNcbiAgICBCLT4-SzogUE9TVHMgZGF0YSBhZ2FpbiAtIGFuZCBzbyBvbi4uLlxuICBlbmRcbiIsIm1lcm1haWQiOnsidGhlbWUiOiJuZXV0cmFsIiwic2VxdWVuY2VEaWFncmFtIjp7ImRpYWdyYW1NYXJnaW5YIjoxNSwiZGlhZ3JhbU1hcmdpblkiOjE1LCJib3hUZXh0TWFyZ2luIjowLCJub3RlTWFyZ2luIjoxNSwibWVzc2FnZU1hcmdpbiI6NDUsIm1pcnJvckFjdG9ycyI6dHJ1ZX19fQ",alt:"Abstract Login and Registration User Flow"})))),Object(r.b)("p",null,"The exact data being fetched and the step ",Object(r.b)("em",{parentName:"p"},'"Processes Login / Registration\nInfo"')," depend, of course, on the actual Strategy being used. But it is important\nto understand that ",Object(r.b)("strong",{parentName:"p"},'"Your Application"'),' is responsible for rendering the\nactual Login and Registration HTML Forms. You can of course implement one app\nfor rendering all the Login, Registration, ... screens, and another app (think\n"Service Oriented Architecture", "Micro-Services" or "Service Mesh") is\nresponsible for rendering your Dashboards, Management Screens, and so on.'),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},'It is highly RECOMMENDED to all the applications (or "services"), including\nORY Kratos, behind a common API Gateway or Reverse Proxy. This greatly reduces\nthe amount of work you have to do to get all the Cookies working properly. We\nRECOMMEND using ',Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"http://github.com/ory/oathkeeper"}),"ORY Oathkeeper")," for this as\nit integrates best with the ORY Ecosystem and because all of our examples use\nORY Oathkeeper. You MAY of course use any other reverse proxy (Envoy, AWS API\nGateway, Ambassador, Nginx, Kong, ...), but we do not have examples or guides\nfor those at this time.")),Object(r.b)("h3",{id:"code"},"Code"),Object(r.b)("p",null,"Because Login and Registration are so similar, we can use one common piece of\ncode to cover both. A functioning example of the code and approach used here can\nbe found on\n",Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"https://github.com/ory/kratos-selfservice-ui-node"}),"github.com/ory/kratos-selfservice-ui-node"),"."),Object(r.b)("p",null,"The code example used here is universal and does not use an SDK because we want\nyou to understand the fundamentals of how this flow works."),Object(r.b)("p",null,"While this example assumes a Server-Side Application, a Client-Side (e.g.\nReactJS) Application would work the same, but use ORY Kratos' Public API\ninstead."),Object(r.b)("pre",null,Object(r.b)("code",Object(n.a)({parentName:"pre"},{className:"language-js"}),"const fetch = require('node-fetch');\n\nconst config = {\n  kratos: {\n    // The browser config key is used to redirect the user. It reflects where ORY Kratos' Public API\n    // is accessible from. Here, we're assuming traffic going to `http://example.org/.ory/kratos/public/`\n    // will be forwarded to ORY Kratos' Public API.\n    browser: 'http://example.org/.ory/kratos/public/',\n\n    // This is where ORY Kratos' Admin API is accessible.\n    admin: 'https://ory-kratos-admin.example-org.vpc/',\n  },\n};\n\n// The parameter \"flow\" can be \"login\" and \"registration\".\n// You would register the two routes in express js like this:\n//\n//  app.get('/auth/registration', authHandler('registration'))\n//  app.get('/auth/login', authHandler('login'))\n\nexport const authHandler = (flow) => (req, res, next) => {\n  // The request ID is used to identify the login and registraion request and\n  // return data like the csrf_token and so on.\n  const request = req.query.request;\n  if (!request) {\n    console.log('No request found in URL, initializing ${flow} flow.');\n    res.redirect(`${config.kratos.browser}/auth/browser/${flow}`);\n    return;\n  }\n\n  // This is the ORY Kratos URL. If this app and ORY Kratos are running\n  // on the same (e.g. Kubernetes) cluster, this should be ORY Kratos's internal hostname.\n  const url = new URL(`${config.kratos.admin}/auth/browser/requests/${flow}`);\n  url.searchParams.set('request', request);\n\n  fetch(url.toString())\n    .then((response) => {\n      // A 404 code means that this code does not exist. We'll retry by re-initiating the flow.\n      if (response.status == 404) {\n        res.redirect(`${config.kratos.browser}/auth/browser/${flow}`);\n        return;\n      }\n\n      return response.json();\n    })\n    .then((request) => {\n      // Request contains all the request data for this Registration request.\n      // You can process that data here, if you want.\n\n      // Lastly, you probably want to render the data using a view (e.g. Jade Template):\n      res.render(flow, request);\n    });\n};\n")),Object(r.b)("p",null,"For details on payloads and potential HTML snippets consult the individual\nSelf-Service Strategies for:"),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},Object(r.b)("a",Object(n.a)({parentName:"li"},{href:"/kratos/docs/v0.1/self-service/strategies/username-email-password"}),"Username and Password Strategy")),Object(r.b)("li",{parentName:"ul"},Object(r.b)("a",Object(n.a)({parentName:"li"},{href:"/kratos/docs/v0.1/self-service/strategies/openid-connect-social-sign-in-oauth2"}),"Social Sign In Strategy"))),Object(r.b)("h3",{id:"server-side-browser-applications"},"Server-Side Browser Applications"),Object(r.b)("p",null,"Let's take a look at the concrete network topologies, calls, and payloads. Here,\nwe're assuming that you're running a server-side browser application (written in\ne.g. PHP, Java, NodeJS) to render the login and registration screen on the\nserver and make all API calls from that server code. The counterpart to this\nwould be a client-side browser application (written in e.g. Vanilla JavaScript,\nJQuery, ReactJS, AngularJS, ...) that uses AJAX requests to fetch data. For\nthese type of applications, read this section first and go to section\n",Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"#client-side-browser-applications"}),"Client-Side Browser Applications")," next."),Object(r.b)("h4",{id:"network-topology"},"Network Topology"),Object(r.b)("p",null,"Your Server-Side Application and ORY Kratos are deployed in a Virtual Private\nCluster that can not be accessed from the public internet directly. Instead,\nonly ORY Oathkeeper can be accessed from the public internet and proxies\nincoming requests to the appropriate service:"),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"Public internet traffic to domain ",Object(r.b)("inlineCode",{parentName:"li"},"example.org")," is sent to ORY Oathkeeper\nwhich in turn:",Object(r.b)("ul",{parentName:"li"},Object(r.b)("li",{parentName:"ul"},"proxies URLs matching ",Object(r.b)("inlineCode",{parentName:"li"},"https://example.org/auth/login")," to your Server-Side\nApplication available at\n",Object(r.b)("inlineCode",{parentName:"li"},"https://your-service-side-application.example-org.vpc/auth/login")),Object(r.b)("li",{parentName:"ul"},"proxies URLs matching ",Object(r.b)("inlineCode",{parentName:"li"},"https://example.org/auth/registration")," to your\nServer-Side Application available at\n",Object(r.b)("inlineCode",{parentName:"li"},"https://your-service-side-application.example-org.vpc/auth/registration")),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"https://example.org/.ory/kratos/public/*")," is proxied to\n",Object(r.b)("inlineCode",{parentName:"li"},"https://ory-kratos-public.example-org.vpc/")))),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"https://ory-kratos-admin.example-org.vpc/")," exposes ORY Kratos' Admin API and\nis not accessible by the open internet and ideally only by Your Server-Side\nApplication."),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"https://ory-kratos-public.example-org.vpc")," exposes ORY Kratos' Public API and\nis ideally only accessible by ORY Oathkeeper."),Object(r.b)("li",{parentName:"ul"},Object(r.b)("inlineCode",{parentName:"li"},"https://your-service-side-application.example-org.vpc")," exposes your\nServer-Side Application and is ideally only accessible by ORY Oathkeeper.")),Object(r.b)("p",null,"The ORY Kratos Admin API is exposed only in the intranet and only the\nServer-Side Application should be able to talk to it."),Object(r.b)("p",null,Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcblxuc3ViZ3JhcGggcGlbUHVibGljIEludGVybmV0XVxuICAgIEJbQnJvd3Nlcl1cbmVuZFxuXG5zdWJncmFwaCB2cGNbVlBDIC8gQ2xvdWQgLyBEb2NrZXIgTmV0d29ya11cbnN1YmdyYXBoIFwiRGVtaWxpdGFyaXplZCBab25lIC8gRE1aXCJcbiAgICBPS1tPUlkgT2F0aGtlZXBlciA6NDQ1NV1cbiAgICBCIC0tPiBPS1xuZW5kXG5cbiAgICBPSyAtLT58XCJGb3J3YXJkcyAvYXV0aC9sb2dpbiB0b1wifCBTQUxJXG4gICAgT0sgLS0-fFwiRm9yd2FyZHMgL2F1dGgvcmVnaXN0cmF0aW9uIHRvXCJ8IFNBTFJcbiAgICBPSyAtLT58XCJGb3J3YXJkcyAvLm9yeS9rcmF0b3MvcHVibGljLyogdG9cInwgS1BcblxuICAgIHN1YmdyYXBoIFwiUHJpdmF0ZSBTdWJuZXQgLyBJbnRyYW5ldFwiXG4gICAgS1sgT1JZIEtyYXRvcyBdXG5cbiAgICBLUChbIE9SWSBLcmF0b3MgUHVibGljIEFQSSBdKVxuICAgIEtBKFsgT1JZIEtyYXRvcyBBZG1pbiBBUEkgXSlcbiAgICBTQSAtLT58XCJ0YWxrcyB0b1wifCBLQVxuICAgIEtBIC0uYmVsb25ncyB0by4tPiBLXG4gICAgS1AgLS5iZWxvbmdzIHRvLi0-IEtcblxuICAgIHN1YmdyYXBoIHNhW1wiWW91ciBBcHBsaWNhdGlvblwiXVxuXG4gICAgICAgIFNBW1wiWW91ciBTZXJ2ZXItU2lkZSBBcHBsaWNhdGlvblwiXVxuICAgICAgICBTQUxJIC0uYmVsb25ncyB0by4tPiBTQVxuICAgICAgICBTQUxSIC0uYmVsb25ncyB0by4tPiBTQVxuICAgICAgICBTQUxJKFtSb3V0ZSAvYXV0aC9sb2dpbl0pIFxuICAgICAgICBTQUxSKFtSb3V0ZSAvYXV0aC9yZWdpc3RyYXRpb25dKSBcbiAgICBlbmRcbiAgICBlbmRcblxuZW5kXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoibmV1dHJhbCIsImZsb3djaGFydCI6eyJyYW5rU3BhY2luZyI6NzAsIm5vZGVTcGFjaW5nIjozMCwiY3VydmUiOiJiYXNpcyJ9fSwidXBkYXRlRWRpdG9yIjpmYWxzZX0"}),Object(r.b)("img",Object(n.a)({parentName:"a"},{src:"https://mermaid.ink/img/eyJjb2RlIjoiZ3JhcGggVERcblxuc3ViZ3JhcGggcGlbUHVibGljIEludGVybmV0XVxuICAgIEJbQnJvd3Nlcl1cbmVuZFxuXG5zdWJncmFwaCB2cGNbVlBDIC8gQ2xvdWQgLyBEb2NrZXIgTmV0d29ya11cbnN1YmdyYXBoIFwiRGVtaWxpdGFyaXplZCBab25lIC8gRE1aXCJcbiAgICBPS1tPUlkgT2F0aGtlZXBlciA6NDQ1NV1cbiAgICBCIC0tPiBPS1xuZW5kXG5cbiAgICBPSyAtLT58XCJGb3J3YXJkcyAvYXV0aC9sb2dpbiB0b1wifCBTQUxJXG4gICAgT0sgLS0-fFwiRm9yd2FyZHMgL2F1dGgvcmVnaXN0cmF0aW9uIHRvXCJ8IFNBTFJcbiAgICBPSyAtLT58XCJGb3J3YXJkcyAvLm9yeS9rcmF0b3MvcHVibGljLyogdG9cInwgS1BcblxuICAgIHN1YmdyYXBoIFwiUHJpdmF0ZSBTdWJuZXQgLyBJbnRyYW5ldFwiXG4gICAgS1sgT1JZIEtyYXRvcyBdXG5cbiAgICBLUChbIE9SWSBLcmF0b3MgUHVibGljIEFQSSBdKVxuICAgIEtBKFsgT1JZIEtyYXRvcyBBZG1pbiBBUEkgXSlcbiAgICBTQSAtLT58XCJ0YWxrcyB0b1wifCBLQVxuICAgIEtBIC0uYmVsb25ncyB0by4tPiBLXG4gICAgS1AgLS5iZWxvbmdzIHRvLi0-IEtcblxuICAgIHN1YmdyYXBoIHNhW1wiWW91ciBBcHBsaWNhdGlvblwiXVxuXG4gICAgICAgIFNBW1wiWW91ciBTZXJ2ZXItU2lkZSBBcHBsaWNhdGlvblwiXVxuICAgICAgICBTQUxJIC0uYmVsb25ncyB0by4tPiBTQVxuICAgICAgICBTQUxSIC0uYmVsb25ncyB0by4tPiBTQVxuICAgICAgICBTQUxJKFtSb3V0ZSAvYXV0aC9sb2dpbl0pIFxuICAgICAgICBTQUxSKFtSb3V0ZSAvYXV0aC9yZWdpc3RyYXRpb25dKSBcbiAgICBlbmRcbiAgICBlbmRcblxuZW5kXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoibmV1dHJhbCIsImZsb3djaGFydCI6eyJyYW5rU3BhY2luZyI6NzAsIm5vZGVTcGFjaW5nIjozMCwiY3VydmUiOiJiYXNpcyJ9fSwidXBkYXRlRWRpdG9yIjpmYWxzZX0",alt:"User Login and Registration Network Topology for Server-Side Applications"})))),Object(r.b)("h4",{id:"user-login-and-user-registration-process-sequence"},"User Login and User Registration Process Sequence"),Object(r.b)("p",null,"The Login and Registration User Flow is composed of several high-level steps\nsummarized in this state diagram:"),Object(r.b)("p",null,Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtXG4gIHMxOiBVc2VyIGJyb3dzZXMgYXBwXG4gIHMyOiBFeGVjdXRlIFwiQmVmb3JlIExvZ2luL1JlZ2lzdHJhdGlvbiBKb2IocylcIlxuICBzMzogVXNlciBJbnRlcmZhY2UgQXBwbGljYXRpb24gcmVuZGVycyBcIkxvZ2luL1JlZ2lzdHJhdGlvbiBSZXF1ZXN0XCJcbiAgczQ6IEV4ZWN1dGUgXCJBZnRlciBMb2dpbi9SZWdpc3RyYXRpb24gSm9iKHMpXCJcbiAgczU6IFVwZGF0ZSBcIkxvZ2luL1JlZ2lzdHJhdGlvbiBSZXF1ZXN0XCIgd2l0aCBFcnJvciBDb250ZXh0KHMpXG4gIHM2OiBMb2dpbi9SZWdpc3RyYXRpb24gc3VjY2Vzc2Z1bFxuXG5cblxuXHRbKl0gLS0-IHMxXG4gIHMxIC0tPiBzMiA6IFVzZXIgY2xpY2tzIFwiTG9nIGluIC8gU2lnbiB1cFwiXG4gIHMyIC0tPiBFcnJvciA6IEEgam9iIGZhaWxzXG4gIHMyIC0tPiBzMyA6IFVzZXIgaXMgcmVkaXJlY3RlZCB0byBMb2dpbi9SZWdpc3RyYXRpb24gVUkgVVJMXG4gIHMzIC0tPiBzNCA6IFVzZXIgcHJvdmlkZXMgdmFsaWQgY3JlZGVudGlhbHMvcmVnaXN0cmF0aW9uIGRhdGFcbiAgczMgLS0-IHM1IDogVXNlciBwcm92aWRlcyBpbnZhbGlkIGNyZWRlbnRpYWxzL3JlZ2lzdHJhdGlvbiBkYXRhXG4gIHM1IC0tPiBzMyA6IFVzZXIgaXMgcmVkaXJlY3RlZCB0byBMb2dpbi9SZWdpc3RyYXRpb24gVUkgVVJMXG4gIHM0IC0tPiBFcnJvciA6IEEgam9iIGZhaWxzXG4gIHM0IC0tPiBzNlxuICBzNiAtLT4gWypdXG5cbiAgRXJyb3IgLS0-IFsqXVxuXG5cbiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9"}),Object(r.b)("img",Object(n.a)({parentName:"a"},{src:"https://mermaid.ink/img/eyJjb2RlIjoic3RhdGVEaWFncmFtXG4gIHMxOiBVc2VyIGJyb3dzZXMgYXBwXG4gIHMyOiBFeGVjdXRlIFwiQmVmb3JlIExvZ2luL1JlZ2lzdHJhdGlvbiBKb2IocylcIlxuICBzMzogVXNlciBJbnRlcmZhY2UgQXBwbGljYXRpb24gcmVuZGVycyBcIkxvZ2luL1JlZ2lzdHJhdGlvbiBSZXF1ZXN0XCJcbiAgczQ6IEV4ZWN1dGUgXCJBZnRlciBMb2dpbi9SZWdpc3RyYXRpb24gSm9iKHMpXCJcbiAgczU6IFVwZGF0ZSBcIkxvZ2luL1JlZ2lzdHJhdGlvbiBSZXF1ZXN0XCIgd2l0aCBFcnJvciBDb250ZXh0KHMpXG4gIHM2OiBMb2dpbi9SZWdpc3RyYXRpb24gc3VjY2Vzc2Z1bFxuXG5cblxuXHRbKl0gLS0-IHMxXG4gIHMxIC0tPiBzMiA6IFVzZXIgY2xpY2tzIFwiTG9nIGluIC8gU2lnbiB1cFwiXG4gIHMyIC0tPiBFcnJvciA6IEEgam9iIGZhaWxzXG4gIHMyIC0tPiBzMyA6IFVzZXIgaXMgcmVkaXJlY3RlZCB0byBMb2dpbi9SZWdpc3RyYXRpb24gVUkgVVJMXG4gIHMzIC0tPiBzNCA6IFVzZXIgcHJvdmlkZXMgdmFsaWQgY3JlZGVudGlhbHMvcmVnaXN0cmF0aW9uIGRhdGFcbiAgczMgLS0-IHM1IDogVXNlciBwcm92aWRlcyBpbnZhbGlkIGNyZWRlbnRpYWxzL3JlZ2lzdHJhdGlvbiBkYXRhXG4gIHM1IC0tPiBzMyA6IFVzZXIgaXMgcmVkaXJlY3RlZCB0byBMb2dpbi9SZWdpc3RyYXRpb24gVUkgVVJMXG4gIHM0IC0tPiBFcnJvciA6IEEgam9iIGZhaWxzXG4gIHM0IC0tPiBzNlxuICBzNiAtLT4gWypdXG5cbiAgRXJyb3IgLS0-IFsqXVxuXG5cbiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9",alt:"User Login and Registration State Machine"})))),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},"The ",Object(r.b)("strong",{parentName:"li"},"Login/Registration User Flow")," is initiated because a link was clicked\nor an action was performed that requires an active user session."),Object(r.b)("li",{parentName:"ol"},"ORY Kratos executes Jobs defined in the ",Object(r.b)("strong",{parentName:"li"},"Before Login/Registration\nWorkflow"),". If a failure occurs, the whole flow is aborted."),Object(r.b)("li",{parentName:"ol"},"The user's browser is redirected to\n",Object(r.b)("inlineCode",{parentName:"li"},"https://example.org/.ory/kratos/public/auth/browser/(login|registration)"),"\n(the notation ",Object(r.b)("inlineCode",{parentName:"li"},"(login|registration)")," expresses the two possibilities of\n",Object(r.b)("inlineCode",{parentName:"li"},"../auth/browser/login")," or ",Object(r.b)("inlineCode",{parentName:"li"},"../auth/browser/registration"),")."),Object(r.b)("li",{parentName:"ol"},"ORY Kratos does some internal processing (e.g. checks if a session cookie is\nset, generates payloads for form fields, sets CSRF token, ...) and redirects\nthe user's browser to the Login UI URL which is defined using the\n",Object(r.b)("inlineCode",{parentName:"li"},"urls.login_ui")," (or ",Object(r.b)("inlineCode",{parentName:"li"},"urls.registration_ui"),") config or ",Object(r.b)("inlineCode",{parentName:"li"},"URLS_LOGIN_UI")," (or\n",Object(r.b)("inlineCode",{parentName:"li"},"URLS_REGISTRATION_UI"),") environment variable, which is set to the ui\nendpoints - for example ",Object(r.b)("inlineCode",{parentName:"li"},"https://example.org/auth/login")," and\n",Object(r.b)("inlineCode",{parentName:"li"},"https://example.org/auth/registration"),"). The user's browser is thus\nredirected to ",Object(r.b)("inlineCode",{parentName:"li"},"https://example.org/auth/(login|registration)?request=abcde"),".\nThe ",Object(r.b)("inlineCode",{parentName:"li"},"request")," query parameter includes a unique ID which will be used to\nfetch contextual data for this login request."),Object(r.b)("li",{parentName:"ol"},"Your Server-Side Application makes a ",Object(r.b)("inlineCode",{parentName:"li"},"GET")," request to\n",Object(r.b)("inlineCode",{parentName:"li"},"https://ory-kratos-admin.example-org.vpc/auth/browser/requests/(login|registration)?request=abcde"),".\nORY Kratos responds with a JSON Payload that contains data (form fields,\nerror messages, ...) for all enabled User Login Strategies:\n",Object(r.b)("inlineCode",{parentName:"li"},'json5 { "id": "abcde", "expires_at": "2020-01-27T09:34:39.3249566Z", "issued_at": "2020-01-27T09:24:39.3249689Z", "request_url": "https://example.org/.ory/kratos/public/auth/browser/(login|registration)", "methods": { "oidc": { "method": "oidc", "config": { /* ... */ } }, "password": { "method": "password", "config": { /* ... */ } } // ... } }')),Object(r.b)("li",{parentName:"ol"},'Your Server-Side applications renders the data however you see fit. The User\ninteracts with it an completes the Login by clicking, for example, the\n"Login", the "Login with Google", ... button.'),Object(r.b)("li",{parentName:"ol"},"The User's browser makes a request to one of ORY Kratos' Strategy URLs (e.g.\n",Object(r.b)("inlineCode",{parentName:"li"},"https://example.org/.ory/kratos/public/auth/browser/methods/password/(login|registration)"),"\nor\n",Object(r.b)("inlineCode",{parentName:"li"},"https://example.org/.ory/kratos/public/auth/browser/methods/oidc/auth/abcde"),").\nORY Kratos validates the User's credentials (when logging in - e.g. Username\nand Password, by performing an OpenID Connect flow, ...) or the registration\nform data (when signing up - e.g. is the E-Mail address valid, is the person\nat least 21 years old, ...):",Object(r.b)("ul",{parentName:"li"},Object(r.b)("li",{parentName:"ul"},"If the credentials / form data is invalid, the Login Request's JSON Payload\nis updated - for example with",Object(r.b)("pre",{parentName:"li"},Object(r.b)("code",Object(n.a)({parentName:"pre"},{className:"language-json5"}),"{\n  id: 'abcde',\n  expires_at: '2020-01-27T10:05:50.1678228Z',\n  issued_at: '2020-01-27T09:55:50.1678348Z',\n  request_url: 'http://127.0.0.1:4455/auth/browser/(login|registration)',\n  methods: {\n    oidc: {\n      method: 'oidc',\n      config: {\n        /* ... */\n      },\n    },\n    password: {\n      method: 'password',\n      config: {\n        /* ... */\n        errors: [\n          {\n            message: 'The provided credentials are invalid. Check for spelling mistakes in your password or username, email address, or phone number.',\n          },\n        ],\n      },\n    },\n  },\n}\n")),"and the user's Browser is redirected back to the Login UI:\n",Object(r.b)("inlineCode",{parentName:"li"},"https://example.org/auth/(login|registration)?request=abcde"),"."),Object(r.b)("li",{parentName:"ul"},"If credentials / data is valid, ORY Kratos proceeds with the next step."),Object(r.b)("li",{parentName:"ul"},"If the flow is a registration request and the registration data is valid,\nthe identity is created."))),Object(r.b)("li",{parentName:"ol"},"ORY Kratos executes Jobs (e.g. redirect somewhere) defined in the ",Object(r.b)("strong",{parentName:"li"},"After\nLogin/Registration Workflow"),". If a failure occurs, the whole flow is\naborted.")),Object(r.b)("p",null,Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gIHBhcnRpY2lwYW50IEIgYXMgQnJvd3NlclxuICBwYXJ0aWNpcGFudCBPIGFzIE9SWSBPYXRoa2VlcGVyXG4gIHBhcnRpY2lwYW50IEtQIGFzIE9SWSBLcmF0b3MgUHVibGljIEFQSVxuICBwYXJ0aWNpcGFudCBBIGFzIFlvdXIgU2VydmVyLVNpZGUgQXBwbGljYXRpb25cbiAgcGFydGljaXBhbnQgS0EgYXMgT1JZIEtyYXRvcyBBZG1pbiBBUElcblxuICBCLT4-K086IEdFVCAvLm9yeS9rcmF0b3MvcHVibGljL2F1dGgvYnJvd3Nlci8obG9naW58cmVnaXN0cmF0aW9uKVxuICBPLT4-K0tQOiBHRVQgL2F1dGgvYnJvd3Nlci8obG9naW58cmVnaXN0cmF0aW9uKVxuICBLUC0tPj5LUDogRXhlY3V0ZSBKb2JzIGRlZmluZWQgaW4gXCJCZWZvcmUgTG9naW4vUmVnaXN0cmF0aW9uIFdvcmtmbG93KHMpXCJcbiAgS1AtLT4-LU86IEhUVFAgMzAyIEZvdW5kIC9hcHAvYXV0aC8obG9naW58cmVnaXN0cmF0aW9uKT9yZXF1ZXN0PWFiY2RlXG4gIE8tLT4-LUI6IEhUVFAgMzAyIEZvdW5kIC9hcHAvYXV0aC8obG9naW58cmVnaXN0cmF0aW9uKT9yZXF1ZXN0PWFiY2RlXG5cbiAgQi0-PitPOiBHRVQgL2FwcC9hdXRoLyhsb2dpbnxyZWdpc3RyYXRpb24pP3JlcXVlc3Q9YWJjZGVcbiAgTy0-PitBOiBHRVQgL2F1dGgvKGxvZ2lufHJlZ2lzdHJhdGlvbik_cmVxdWVzdD1hYmNkZVxuICBBLT4-K0tBOiBHRVQgL2F1dGgvYnJvd3Nlci9yZXF1ZXN0cy8obG9naW58cmVnaXN0cmF0aW9uKT9yZXF1ZXN0PWFiY2RlXG4gIEtBLT4-LUE6IFNlbmRzIExvZ2luL1JlZ2lzdHJhdGlvbiBSZXF1ZXN0IEpTT04gUGF5bG9hZFxuICBOb3RlIG92ZXIgQSxLQTogIHtcIm1ldGhvZHNcIjp7XCJwYXNzd29yZFwiOi4uLixcIm9pZGNcIjouLn19XG4gIEEtLT4-QTogR2VuZXJhdGUgYW5kIHJlbmRlciBIVE1MXG4gIEEtLT4-LU86IFJldHVybiBIVE1MIChGb3JtLCAuLi4pXG4gIE8tLT4-LUI6IFJldHVybiBIVE1MIChGb3JtLCAuLi4pXG5cbiAgQi0tPj5COiBGaWxsIG91dCBIVE1MXG5cbiAgQi0-PitPOiBQT1NUIEhUTUwgRm9ybVxuICBPLT4-K0tQOiBQT1NUIEhUTUwgRm9ybVxuICBLUC0tPj5LUDogQ2hlY2tzIGxvZ2luIC8gcmVnaXN0cmF0aW9uIGRhdGFcblxuXG4gIGFsdCBMb2dpbiBkYXRhIGlzIHZhbGlkXG4gICAgS1AtLT4-LUtQOiBFeGVjdXRlIEpvYnMgZGVmaW5lZCBpbiBcIkFmdGVyIExvZ2luIFdvcmtmbG93KHMpXCJcbiAgICBLUC0tPj5POiBIVFRQIDMwMiBGb3VuZCAvYXBwL2Rhc2hib2FyZFxuICAgIE5vdGUgb3ZlciBLUCxCOiBTZXQtQ29va2llOiBhdXRoX3Nlc3Npb249Li4uXG4gICAgTy0tPj4tQjogSFRUUCAzMDIgRm91bmQgL2FwcC9kYXNoYm9hcmRcbiAgICBCLT4-TzogR0VUIC9hcHAvZGFzaGJvYXJkXG4gICAgTy0tPktBOiBWYWxpZGF0ZXMgU2Vzc2lvbiBDb29raWVcbiAgICBPLT4-QTogR0VUIC9kYXNoYm9hcmRcbiAgZWxzZSBMb2dpbiBkYXRhIGlzIGludmFsaWRcbiAgICBOb3RlIG92ZXIgS1AsQjogVXNlciByZXRyaWVzIGxvZ2luIC8gcmVnaXN0cmF0aW9uXG4gICAgS1AtLT4-TzogSFRUUCAzMDIgRm91bmQgL2FwcC9hdXRoLyhsb2dpbnxyZWdpc3RyYXRpb24pP3JlcXVlc3Q9YWJjZGVcbiAgICBPLS0-PkI6IEhUVFAgMzAyIEZvdW5kIC9hcHAvYXV0aC8obG9naW58cmVnaXN0cmF0aW9uKT9yZXF1ZXN0PWFiY2RlXG4gIGVuZFxuICAiLCJtZXJtYWlkIjp7InRoZW1lIjoibmV1dHJhbCIsInNlcXVlbmNlRGlhZ3JhbSI6eyJkaWFncmFtTWFyZ2luWCI6MTUsImRpYWdyYW1NYXJnaW5ZIjoxNSwiYm94VGV4dE1hcmdpbiI6MSwibm90ZU1hcmdpbiI6MTAsIm1lc3NhZ2VNYXJnaW4iOjU1LCJtaXJyb3JBY3RvcnMiOnRydWV9fSwidXBkYXRlRWRpdG9yIjpmYWxzZX0"}),Object(r.b)("img",Object(n.a)({parentName:"a"},{src:"https://mermaid.ink/img/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gIHBhcnRpY2lwYW50IEIgYXMgQnJvd3NlclxuICBwYXJ0aWNpcGFudCBPIGFzIE9SWSBPYXRoa2VlcGVyXG4gIHBhcnRpY2lwYW50IEtQIGFzIE9SWSBLcmF0b3MgUHVibGljIEFQSVxuICBwYXJ0aWNpcGFudCBBIGFzIFlvdXIgU2VydmVyLVNpZGUgQXBwbGljYXRpb25cbiAgcGFydGljaXBhbnQgS0EgYXMgT1JZIEtyYXRvcyBBZG1pbiBBUElcblxuICBCLT4-K086IEdFVCAvLm9yeS9rcmF0b3MvcHVibGljL2F1dGgvYnJvd3Nlci8obG9naW58cmVnaXN0cmF0aW9uKVxuICBPLT4-K0tQOiBHRVQgL2F1dGgvYnJvd3Nlci8obG9naW58cmVnaXN0cmF0aW9uKVxuICBLUC0tPj5LUDogRXhlY3V0ZSBKb2JzIGRlZmluZWQgaW4gXCJCZWZvcmUgTG9naW4vUmVnaXN0cmF0aW9uIFdvcmtmbG93KHMpXCJcbiAgS1AtLT4-LU86IEhUVFAgMzAyIEZvdW5kIC9hcHAvYXV0aC8obG9naW58cmVnaXN0cmF0aW9uKT9yZXF1ZXN0PWFiY2RlXG4gIE8tLT4-LUI6IEhUVFAgMzAyIEZvdW5kIC9hcHAvYXV0aC8obG9naW58cmVnaXN0cmF0aW9uKT9yZXF1ZXN0PWFiY2RlXG5cbiAgQi0-PitPOiBHRVQgL2FwcC9hdXRoLyhsb2dpbnxyZWdpc3RyYXRpb24pP3JlcXVlc3Q9YWJjZGVcbiAgTy0-PitBOiBHRVQgL2F1dGgvKGxvZ2lufHJlZ2lzdHJhdGlvbik_cmVxdWVzdD1hYmNkZVxuICBBLT4-K0tBOiBHRVQgL2F1dGgvYnJvd3Nlci9yZXF1ZXN0cy8obG9naW58cmVnaXN0cmF0aW9uKT9yZXF1ZXN0PWFiY2RlXG4gIEtBLT4-LUE6IFNlbmRzIExvZ2luL1JlZ2lzdHJhdGlvbiBSZXF1ZXN0IEpTT04gUGF5bG9hZFxuICBOb3RlIG92ZXIgQSxLQTogIHtcIm1ldGhvZHNcIjp7XCJwYXNzd29yZFwiOi4uLixcIm9pZGNcIjouLn19XG4gIEEtLT4-QTogR2VuZXJhdGUgYW5kIHJlbmRlciBIVE1MXG4gIEEtLT4-LU86IFJldHVybiBIVE1MIChGb3JtLCAuLi4pXG4gIE8tLT4-LUI6IFJldHVybiBIVE1MIChGb3JtLCAuLi4pXG5cbiAgQi0tPj5COiBGaWxsIG91dCBIVE1MXG5cbiAgQi0-PitPOiBQT1NUIEhUTUwgRm9ybVxuICBPLT4-K0tQOiBQT1NUIEhUTUwgRm9ybVxuICBLUC0tPj5LUDogQ2hlY2tzIGxvZ2luIC8gcmVnaXN0cmF0aW9uIGRhdGFcblxuXG4gIGFsdCBMb2dpbiBkYXRhIGlzIHZhbGlkXG4gICAgS1AtLT4-LUtQOiBFeGVjdXRlIEpvYnMgZGVmaW5lZCBpbiBcIkFmdGVyIExvZ2luIFdvcmtmbG93KHMpXCJcbiAgICBLUC0tPj5POiBIVFRQIDMwMiBGb3VuZCAvYXBwL2Rhc2hib2FyZFxuICAgIE5vdGUgb3ZlciBLUCxCOiBTZXQtQ29va2llOiBhdXRoX3Nlc3Npb249Li4uXG4gICAgTy0tPj4tQjogSFRUUCAzMDIgRm91bmQgL2FwcC9kYXNoYm9hcmRcbiAgICBCLT4-TzogR0VUIC9hcHAvZGFzaGJvYXJkXG4gICAgTy0tPktBOiBWYWxpZGF0ZXMgU2Vzc2lvbiBDb29raWVcbiAgICBPLT4-QTogR0VUIC9kYXNoYm9hcmRcbiAgZWxzZSBMb2dpbiBkYXRhIGlzIGludmFsaWRcbiAgICBOb3RlIG92ZXIgS1AsQjogVXNlciByZXRyaWVzIGxvZ2luIC8gcmVnaXN0cmF0aW9uXG4gICAgS1AtLT4-TzogSFRUUCAzMDIgRm91bmQgL2FwcC9hdXRoLyhsb2dpbnxyZWdpc3RyYXRpb24pP3JlcXVlc3Q9YWJjZGVcbiAgICBPLS0-PkI6IEhUVFAgMzAyIEZvdW5kIC9hcHAvYXV0aC8obG9naW58cmVnaXN0cmF0aW9uKT9yZXF1ZXN0PWFiY2RlXG4gIGVuZFxuICAiLCJtZXJtYWlkIjp7InRoZW1lIjoibmV1dHJhbCIsInNlcXVlbmNlRGlhZ3JhbSI6eyJkaWFncmFtTWFyZ2luWCI6MTUsImRpYWdyYW1NYXJnaW5ZIjoxNSwiYm94VGV4dE1hcmdpbiI6MSwibm90ZU1hcmdpbiI6MTAsIm1lc3NhZ2VNYXJnaW4iOjU1LCJtaXJyb3JBY3RvcnMiOnRydWV9fSwidXBkYXRlRWRpdG9yIjpmYWxzZX0",alt:"User Login Sequence Diagram for Server-Side Applications"})))),Object(r.b)("h3",{id:"client-side-browser-applications"},"Client-Side Browser Applications"),Object(r.b)("p",null,"Because Client-Side Browser Applications do not have access to ORY Kratos' Admin\nAPI, they must use the ORY Kratos Public API instead. The flow for a Client-Side\nBrowser Application is almost the exact same as the one for Server-Side\nApplications, with the small difference that\n",Object(r.b)("inlineCode",{parentName:"p"},"https://example.org/.ory/kratos/public/auth/browser/requests/login?request=abcde"),"\nwould be called via AJAX instead of making a request to\n",Object(r.b)("inlineCode",{parentName:"p"},"https://ory-kratos-admin.example-org.vpc/auth/browser/requests/login?request=abcde"),"."),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"To prevent brute force, guessing, session injection, and other attacks, it is\nrequired that cookies are working for this endpoint. The cookie set in the\ninitial HTTP request made to\n",Object(r.b)("inlineCode",{parentName:"p"},"https://example.org/.ory/kratos/public/auth/browser/login")," MUST be set and\navailable when calling this endpoint!")),Object(r.b)("h2",{id:"self-service-user-login-and-user-registration-for-api-clients"},"Self-Service User Login and User Registration for API Clients"),Object(r.b)("p",null,"Will be addressed in a future release."),Object(r.b)("h2",{id:"executing-jobs-before-user-login"},"Executing Jobs before User Login"),Object(r.b)("p",null,"ORY Kratos allows you to configure jobs that run before the Login Request is\ngenerated. This may be helpful if you'd like to restrict logins to IPs coming\nfrom your internal network or other logic."),Object(r.b)("p",null,"You can find available ",Object(r.b)("inlineCode",{parentName:"p"},"before")," jobs in\n",Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"/kratos/docs/v0.1/self-service/workflows/jobs/before#user-login"}),"Self-Service Before Login Jobs")," and\nconfigure them using the ORY Kratos configuration file:"),Object(r.b)("pre",null,Object(r.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"selfservice:\n  login:\n    before:\n      - run: <job-name>\n        config:\n          # <job-config>\n")),Object(r.b)("h2",{id:"executing-jobs-after-user-login"},"Executing Jobs after User Login"),Object(r.b)("p",null,"ORY Kratos allows you to configure jobs that run before the Login Request is\ngenerated. This may be helpful if you'd like to restrict logins to IPs coming\nfrom your internal network or other logic."),Object(r.b)("p",null,"You can find available ",Object(r.b)("inlineCode",{parentName:"p"},"after")," jobs in\n",Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"/kratos/docs/v0.1/self-service/workflows/jobs/after#user-login"}),"Self-Service After Login Jobs")," and\nconfigure them using the ORY Kratos configuration file:"),Object(r.b)("pre",null,Object(r.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"selfservice:\n  after:\n    <strategy>:\n      - run: <job-name>\n        config:\n          # <job-config>\n")),Object(r.b)("p",null,"It's possible to define jobs running after login for each individual User Login\nFlow Strategy (e.g. ",Object(r.b)("inlineCode",{parentName:"p"},"password"),", ",Object(r.b)("inlineCode",{parentName:"p"},"oidc"),")."),Object(r.b)("h2",{id:"executing-jobs-before-user-registration"},"Executing Jobs before User Registration"),Object(r.b)("p",null,"ORY Kratos allows you to configure jobs that run before the Registration Request\nis generated. This may be helpful if you'd like to restrict registrations to IPs\ncoming from your internal network or other logic."),Object(r.b)("p",null,"You can find available ",Object(r.b)("inlineCode",{parentName:"p"},"before")," jobs in\n",Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"/kratos/docs/v0.1/self-service/workflows/jobs/before#user-registration"}),"Self-Service Before Registration Jobs"),"\nand configure them using the ORY Kratos configuration file:"),Object(r.b)("pre",null,Object(r.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"selfservice:\n  registration:\n    before:\n      - run: <job-name>\n        config:\n          # <job-config>\n")),Object(r.b)("h2",{id:"executing-jobs-after-user-registration"},"Executing Jobs after User Registration"),Object(r.b)("p",null,"ORY Kratos allows you to configure jobs that run before the Registration Request\nis generated. This may be helpful if you'd like to restrict registrations to IPs\ncoming from your internal network or other logic."),Object(r.b)("p",null,"You can find available ",Object(r.b)("inlineCode",{parentName:"p"},"after")," jobs in\n",Object(r.b)("a",Object(n.a)({parentName:"p"},{href:"/kratos/docs/v0.1/self-service/workflows/jobs/after#user-registration"}),"Self-Service After Registration Jobs"),"\nand configure them using the ORY Kratos configuration file:"),Object(r.b)("pre",null,Object(r.b)("code",Object(n.a)({parentName:"pre"},{className:"language-yaml"}),"selfservice:\n  after:\n    <strategy>:\n      - run: <job-name>\n        config:\n          # <job-config>\n")),Object(r.b)("p",null,"It's possible to define jobs running after registration for each individual User\nRegistration Flow Strategy (e.g. ",Object(r.b)("inlineCode",{parentName:"p"},"password"),", ",Object(r.b)("inlineCode",{parentName:"p"},"oidc"),")."))}b.isMDXComponent=!0},324:function(e,t,i){"use strict";i.d(t,"a",(function(){return g})),i.d(t,"b",(function(){return p}));var n=i(0),a=i.n(n);function r(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function o(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function s(e){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?o(Object(i),!0).forEach((function(t){r(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):o(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function l(e,t){if(null==e)return{};var i,n,a=function(e,t){if(null==e)return{};var i,n,a={},r=Object.keys(e);for(n=0;n<r.length;n++)i=r[n],t.indexOf(i)>=0||(a[i]=e[i]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n<r.length;n++)i=r[n],t.indexOf(i)>=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(a[i]=e[i])}return a}var c=a.a.createContext({}),b=function(e){var t=a.a.useContext(c),i=t;return e&&(i="function"==typeof e?e(t):s(s({},t),e)),i},g=function(e){var t=b(e.components);return a.a.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.a.createElement(a.a.Fragment,{},t)}},u=a.a.forwardRef((function(e,t){var i=e.components,n=e.mdxType,r=e.originalType,o=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),g=b(i),u=n,p=g["".concat(o,".").concat(u)]||g[u]||d[u]||r;return i?a.a.createElement(p,s(s({ref:t},c),{},{components:i})):a.a.createElement(p,s({ref:t},c))}));function p(e,t){var i=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=i.length,o=new Array(r);o[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:n,o[1]=s;for(var c=2;c<r;c++)o[c]=i[c];return a.a.createElement.apply(null,o)}return a.a.createElement.apply(null,i)}u.displayName="MDXCreateElement"}}]);