miniature-sunset-64101
03/15/2023, 9:58 AMCould not find a strategy to sign you up with. Did you fill out the form correctly?
When using the Kratos browser API with Axios, but I don't get that error when passing the exact same data over Postman. Can anybody help me see what I'm missing?
I have a hunch it has something to do with Axios not being able to access http-only cookies, but then how do I work around that? How is Postman making it work?miniature-sunset-64101
03/15/2023, 10:04 AM/self-service/registration/browser
response:
{
"id": "88882fef-3ab1-41d6-99e7-6b89fa16f49a",
"oauth2_login_challenge": null,
"type": "browser",
"expires_at": "2023-03-15T10:13:26.780138765Z",
"issued_at": "2023-03-15T09:13:26.780138765Z",
"request_url": "<https://agitated-bose-683mbbds9i.projects.oryapis.com/self-service/registration/browser>",
"ui": {
"action": "<https://agitated-bose-683mbbds9i.projects.oryapis.com/self-service/registration?flow=88882fef-3ab1-41d6-99e7-6b89fa16f49a>",
"method": "POST",
"nodes": [
{
"type": "input",
"group": "default",
"attributes": {
"name": "csrf_token",
"type": "hidden",
"value": "lWqRsb/jm22038qqGFb4whgoYhsimmTWoWCCKtPjAAKHLXLYbsM9ZOHAyP2T6P8d5knhgGG2GWT+4yjSZ5xX3g==",
"required": true,
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {}
},
{
"type": "input",
"group": "password",
"attributes": {
"name": "traits.email",
"type": "email",
"required": true,
"autocomplete": "email",
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {
"label": {
"id": 1070002,
"text": "E-Mail",
"type": "info"
}
}
},
{
"type": "input",
"group": "password",
"attributes": {
"name": "password",
"type": "password",
"required": true,
"autocomplete": "new-password",
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {
"label": {
"id": 1070001,
"text": "Password",
"type": "info"
}
}
},
{
"type": "input",
"group": "password",
"attributes": {
"name": "method",
"type": "submit",
"value": "password",
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {
"label": {
"id": 1040001,
"text": "Sign up",
"type": "info",
"context": {}
}
}
}
]
}
}
then, POST to: /self-service/registration?flow=88882fef-3ab1-41d6-99e7-6b89fa16f49a
with body:
{
"csrf_token": "lWqRsb/jm22038qqGFb4whgoYhsimmTWoWCCKtPjAAKHLXLYbsM9ZOHAyP2T6P8d5knhgGG2GWT+4yjSZ5xX3g==",
"password": "f@kepassword1!",
"method": "password",
"traits": {
"email": "<mailto:test3@postman.com|test3@postman.com>"
}
}
response:
{
"session": {
"id": "776896f6-0911-43b1-81d2-426742255b63",
"active": true,
"expires_at": "2023-03-18T09:15:23.435603784Z",
"authenticated_at": "2023-03-15T09:15:23.491108036Z",
"authenticator_assurance_level": "aal1",
"authentication_methods": [
{
"method": "password",
"aal": "aal1",
"completed_at": "2023-03-15T09:15:23.435750204Z"
}
],
"issued_at": "2023-03-15T09:15:23.435603784Z",
"identity": {
"id": "ca3c54ea-486e-4629-92c2-ab0c49cded3e",
"schema_id": "<preset://email>",
"schema_url": "<https://agitated-bose-683mbbds9i.projects.oryapis.com/schemas/cHJlc2V0Oi8vZW1haWw>",
"state": "active",
"state_changed_at": "2023-03-15T09:15:23.384434693Z",
"traits": {
"email": "<mailto:test3@postman.com|test3@postman.com>"
},
"verifiable_addresses": [
{
"id": "0e5cd7b7-27ae-4623-9068-04f44b700c2b",
"value": "<mailto:test3@postman.com|test3@postman.com>",
"verified": false,
"via": "email",
"status": "sent",
"created_at": "2023-03-15T09:15:23.392703Z",
"updated_at": "2023-03-15T09:15:23.392703Z"
}
],
"recovery_addresses": [
{
"id": "1710cf19-90ca-4308-aa5a-02da1cc4bbee",
"value": "<mailto:test3@postman.com|test3@postman.com>",
"via": "email",
"created_at": "2023-03-15T09:15:23.402424Z",
"updated_at": "2023-03-15T09:15:23.402424Z"
}
],
"metadata_public": null,
"created_at": "2023-03-15T09:15:23.38698Z",
"updated_at": "2023-03-15T09:15:23.38698Z"
},
"devices": [
{
"id": "42cab2f1-5595-4ff7-aad8-f13fbd83c050",
"ip_address": "18.200.137.213",
"user_agent": "Go-http-client/1.1",
"location": "Dublin, IE"
}
]
},
"identity": {
"id": "ca3c54ea-486e-4629-92c2-ab0c49cded3e",
"schema_id": "<preset://email>",
"schema_url": "<https://agitated-bose-683mbbds9i.projects.oryapis.com/schemas/cHJlc2V0Oi8vZW1haWw>",
"state": "active",
"state_changed_at": "2023-03-15T09:15:23.384434693Z",
"traits": {
"email": "<mailto:test3@postman.com|test3@postman.com>"
},
"verifiable_addresses": [
{
"id": "0e5cd7b7-27ae-4623-9068-04f44b700c2b",
"value": "<mailto:test3@postman.com|test3@postman.com>",
"verified": false,
"via": "email",
"status": "sent",
"created_at": "2023-03-15T09:15:23.392703Z",
"updated_at": "2023-03-15T09:15:23.392703Z"
}
],
"recovery_addresses": [
{
"id": "1710cf19-90ca-4308-aa5a-02da1cc4bbee",
"value": "<mailto:test3@postman.com|test3@postman.com>",
"via": "email",
"created_at": "2023-03-15T09:15:23.402424Z",
"updated_at": "2023-03-15T09:15:23.402424Z"
}
],
"metadata_public": null,
"created_at": "2023-03-15T09:15:23.38698Z",
"updated_at": "2023-03-15T09:15:23.38698Z"
}
}
So far so good, but...miniature-sunset-64101
03/15/2023, 10:15 AM/self-service/registration/browser
Response
{
"id": "7a8c2546-f12b-43de-b190-7d573b7f37d5",
"oauth2_login_challenge": null,
"type": "browser",
"expires_at": "2023-03-15T10:56:18.007880493Z",
"issued_at": "2023-03-15T09:56:18.007880493Z",
"request_url": "<http://localhost:4000/self-service/registration/browser>",
"ui": {
"action": "<http://localhost:4000/self-service/registration?flow=7a8c2546-f12b-43de-b190-7d573b7f37d5>",
"method": "POST",
"nodes": [
{
"type": "input",
"group": "default",
"attributes": {
"name": "csrf_token",
"type": "hidden",
"value": "iW+3r+V+kThXxNNo3lWSd8/ZyMBYcq03Aifr2Zj2QAlOzuExQBzlk3MB8EJvoVwI+u9SBH6I6wl5zOKZcJYZCw==",
"required": true,
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {}
},
{
"type": "input",
"group": "password",
"attributes": {
"name": "traits.email",
"type": "email",
"required": true,
"autocomplete": "email",
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {
"label": {
"id": 1070002,
"text": "E-Mail",
"type": "info"
}
}
},
{
"type": "input",
"group": "password",
"attributes": {
"name": "password",
"type": "password",
"required": true,
"autocomplete": "new-password",
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {
"label": {
"id": 1070001,
"text": "Password",
"type": "info"
}
}
},
{
"type": "input",
"group": "password",
"attributes": {
"name": "method",
"type": "submit",
"value": "password",
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {
"label": {
"id": 1040001,
"text": "Sign up",
"type": "info",
"context": {}
}
}
}
]
}
}
then, POST to: <http://localhost:4000/self-service/registration?flow=7a8c2546-f12b-43de-b190-7d573b7f37d5>
with body:
{
"csrf_token": "iW+3r+V+kThXxNNo3lWSd8/ZyMBYcq03Aifr2Zj2QAlOzuExQBzlk3MB8EJvoVwI+u9SBH6I6wl5zOKZcJYZCw==",
"password": "f@kepassword1!",
"method": "password",
"traits": {
"email": "<mailto:test3@postman.com|test3@postman.com>"
}
}
response:
{
"id": "7a8c2546-f12b-43de-b190-7d573b7f37d5",
"oauth2_login_challenge": null,
"type": "browser",
"expires_at": "2023-03-15T10:56:18.00788Z",
"issued_at": "2023-03-15T09:56:18.00788Z",
"request_url": "<http://localhost:4000/self-service/registration/browser>",
"ui": {
"action": "<http://localhost:4000/self-service/registration?flow=7a8c2546-f12b-43de-b190-7d573b7f37d5>",
"method": "POST",
"nodes": [
{
"type": "input",
"group": "default",
"attributes": {
"name": "csrf_token",
"type": "hidden",
"value": "iW+3r+V+kThXxNNo3lWSd8/ZyMBYcq03Aifr2Zj2QAlOzuExQBzlk3MB8EJvoVwI+u9SBH6I6wl5zOKZcJYZCw==",
"required": true,
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {}
},
{
"type": "input",
"group": "password",
"attributes": {
"name": "traits.email",
"type": "email",
"required": true,
"autocomplete": "email",
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {
"label": {
"id": 1070002,
"text": "E-Mail",
"type": "info"
}
}
},
{
"type": "input",
"group": "password",
"attributes": {
"name": "password",
"type": "password",
"required": true,
"autocomplete": "new-password",
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {
"label": {
"id": 1070001,
"text": "Password",
"type": "info"
}
}
},
{
"type": "input",
"group": "password",
"attributes": {
"name": "method",
"type": "submit",
"value": "password",
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {
"label": {
"id": 1040001,
"text": "Sign up",
"type": "info",
"context": {}
}
}
}
],
"messages": [
{
"id": 4010003,
"text": "Could not find a strategy to sign you up with. Did you fill out the form correctly?",
"type": "error"
}
]
}
}
Why?proud-plumber-24205
03/15/2023, 10:24 AMminiature-sunset-64101
03/15/2023, 10:26 AMproud-plumber-24205
03/15/2023, 10:26 AMproud-plumber-24205
03/15/2023, 10:27 AMminiature-sunset-64101
03/15/2023, 10:28 AMproud-plumber-24205
03/15/2023, 10:28 AMminiature-sunset-64101
03/15/2023, 10:29 AMproud-plumber-24205
03/15/2023, 10:31 AM@ory/client
) to get the data and pass it on to Ory Elements to render it for you.miniature-sunset-64101
03/15/2023, 11:08 AMminiature-sunset-64101
03/15/2023, 11:08 AMminiature-sunset-64101
03/15/2023, 11:24 AMproud-plumber-24205
03/15/2023, 11:24 AMminiature-sunset-64101
03/15/2023, 12:20 PMimport {Configuration as OryConfiguration} from "@ory/client";
import {FrontendApiFp as OryFrontendApi} from "@ory/client/dist/api";
/* Ory */
const oryConfiguration = new OryConfiguration({
basePath: process.env.NEXT_PUBLIC_ORY_API_URL
});
const oryAPI = new OryFrontendApi(oryConfiguration);
oryAPI.createBrowserRegistrationFlow().then(async (flow) => {
const registrationFlowResponse = await flow();
const csrfToken = registrationFlowResponse.data.ui.nodes.filter((node) => node.attributes.name === "csrf_token").pop().attributes.value;
<http://console.info|console.info>('Ory Registration Flow Response -->', registrationFlowResponse);
<http://console.info|console.info>('Ory Registration CSRF Token -->', csrfToken);
oryAPI.updateRegistrationFlow(registrationFlowResponse.data.id, {
"csrf_token": csrfToken,
"password": "Mielie88!",
"method": "password",
"traits": {
"email": "<mailto:testsdk@postman.com|testsdk@postman.com>"
}
}).then(async (flow) => {
const registrationResponse = await flow();
<http://console.info|console.info>('Ory Registration Response -->', registrationResponse);
});
}).catch((error) => {
console.error("Ory Registration Error --->", error);
});
/* END Ory */
However I feel like:
const csrfToken = registrationFlowResponse.data.ui.nodes.filter((node) => node.attributes.name === "csrf_token").pop().attributes.value;
is not quite correct, which is why I get the following response:
{
"error": {
"id": "security_csrf_violation",
"code": 403,
"status": "Forbidden",
"request": "2f16d9c2-5ed9-9133-bcb6-37f88623f6ae",
"reason": "Please retry the flow and optionally clear your cookies. The request was rejected to protect you from Cross-Site-Request-Forgery (CSRF) which could cause account takeover, leaking personal information, and other serious security issues.",
"details": {
"docs": "<https://www.ory.sh/kratos/docs/debug/csrf>",
"hint": "The anti-CSRF cookie was found but the CSRF token was not included in the HTTP request body (csrf_token) nor in the HTTP Header (X-CSRF-Token).",
"reject_reason": "The HTTP Cookie Header was set and a CSRF token was sent but they do not match. We recommend deleting all cookies for this domain and retrying the flow."
},
"message": "the request was rejected to protect you from Cross-Site-Request-Forgery"
}
}
@proud-plumber-24205, what is the proper way to ensure that the SDK uses the correct CSRF? Is this supposed to be automatic or is my approach wrong?proud-plumber-24205
03/15/2023, 12:29 PMconst frontend = new FrontendApi(
new Configuration({
basePath: "<http://localhost:4000>", // Use your local Ory Tunnel URL
baseOptions: {
withCredentials: true, // we need to include cookies
},
}),
)
https://www.ory.sh/docs/kratos/bring-your-own-ui/custom-ui-basic-integration#create-login-flowproud-plumber-24205
03/15/2023, 12:30 PMminiature-sunset-64101
03/15/2023, 12:34 PMproud-plumber-24205
03/15/2023, 12:35 PM