ory / kratos

The most scalable and customizable identity server on the market. Replace your Homegrown, Auth0, Okta, Firebase with better UX and DX. Has all the tablestakes: Passkeys, Social Sign In, Multi-Factor Auth, SMS, SAML, TOTP, and more. Written in Go, cloud native, headless, API-first. Available as a service on Ory Network and for self-hosters.
https://www.ory.sh/?utm_source=github&utm_medium=banner&utm_campaign=kratos
Apache License 2.0
11.19k stars 959 forks source link

CSRF token is missing or invalid #561

Closed leapit closed 4 years ago

leapit commented 4 years ago

Use api for login

As follow two documents

https://www.ory.sh/kratos/docs/reference/api#initialize-browser-based-login-user-flow https://www.ory.sh/kratos/docs/reference/api#get-the-request-context-of-browser-based-login-user-flows

I test login,for two steps, 1.init flow,get request id 2.use form post login

code as below(already register the identifier via kratos-selfservice-ui-node),

const fetch = require('node-fetch');
const url = require('url');

const kratos_admin_url='http://127.0.0.1:4433/self-service/browser/flows/login'
const headers = {
  'Accept': 'application/json'
}

const identifier = 'my email' //exist
const password = 'my password'

;(async () => {
    const request = await fetch(kratos_admin_url, {
        method: 'get',
        headers: headers
  });
    const request_id = await request.url;
  const url_parts = url.parse(request_id, true);
  const query = url_parts.query;

  const json = await fetch(`http://127.0.0.1:4434/self-service/browser/flows/requests/login?request=${query.request}`, {
        method: 'get',
        headers: headers
  });

  const body = await json.json()
  const form = await fetch(body.methods.password.config.action, {
        method: 'post',
        body: {'identifier':identifier,'password':password,'csrf_token':body.methods.password.config.fields[2].value},
        headers: headers
  });

  const res = await form.json()
  console.log(res)

})();

and got output

{ error:
   { code: 400,
     status: 'Bad Request',
     reason: 'CSRF token is missing or invalid.',
     message: 'The request was malformed or contained invalid parameters' } }

Any misstake or misunderstanding?

aeneasr commented 4 years ago

The first request to http://127.0.0.1:4433/self-service/browser/flows/login is not supposed to be called using AJAX or fetch. You are supposed to redirect the user to that endpoint, e.g. with <a href="'http://127.0.0.1:4433/self-service/browser/flows/login">Login</a>.

See https://www.ory.sh/kratos/docs/self-service/flows/user-login-user-registration#server-side-browser-applications

leapit commented 4 years ago
Screen Shot 2020-07-09 at 6 31 49 AM

@aeneasr As i described above,I have many apps,will use kratos verify identity,between my app(node js) and kratos no bowser,how shall I use kratos api from my app to send identifier and password to kratos,and got jwt?

vkiller commented 4 years ago

@aeneasr Often,just as @leapit said,we have no server side bowser application,just two parts,one is pure client side,e.g. vue/react/angular,the login designed at client side,the other side is pure server code,e.g. go/node/java,without a pug/hbs login design as kratos-selfservice-ui-node.

There should be an api from pure server code to kratos,otherwise developer have to change a lot about his server side application, at least have to add a template(hbs/pug) for user login.

zepatrik commented 4 years ago

Sure @leapit @vkiller that API is required and will be added in a future release but we're not there yet. Kratos is still alpha as crucial features like this are missing. For now you can only emulate a browser client, sorry for that. https://www.ory.sh/kratos/docs/self-service/flows/user-login-user-registration/#self-service-user-login-and-user-registration-for-api-clients

aeneasr commented 4 years ago

@vkiller you can implement Kratos with a SPA today, just don't make an AJAX request to the first endpoint :)

vkiller commented 4 years ago

Thanks @aeneasr @zepatrik ,wait for new updates