bland-finland-95044
12/18/2024, 7:28 PMbrief-egg-61061
12/18/2024, 7:28 PMbrief-egg-61061
12/18/2024, 7:28 PM/sessions/whoami
. [Low latency with Edge Sessions](https://www.ory.sh/docs/concepts/cache) 3. There's an open issue regarding poor query performance for permission checks in Ory Keto as the traversal width increases: - For a specific use case with 200 relationships, check times could exceed 1 second. - This issue suggests that permission checks can potentially be slow in certain scenarios. [Github Issue: Poor query performance as traversal width increases](https://github.com/ory/keto/issues/1519) While these benchmarks and performance metrics don't directly answer your question about the permission API's response times, they provide a general idea of the performance characteristics in Ory's ecosystem. The actual response times for the permission API would likely depend on various factors such as the complexity of the permission model, the number of relationships, and the specific deployment configuration.bland-finland-95044
12/24/2024, 5:34 PMbrief-egg-61061
12/24/2024, 5:34 PMbrief-egg-61061
12/24/2024, 5:34 PMtypescript class ScopedResource implements Namespace { related: { managers: User[] customers: Customer[] } permits = { access: (ctx: Context): boolean => this.related.managers.includes(ctx.subject) || this.related.customers.traverse((customer) => customer.permits.access(ctx)) } }
[What is the Ory Permission Language](https://www.ory.sh/what-is-the-ory-permission-language/#the-ory-permission-language) 3. Ory Permissions supports the concept of subject sets, which can be used to create indirect relationships. This might be useful for handling nested structures: "Subject sets also represent all intermediary nodes in the graph of relations." [Ory Permissions Subjects documentation](https://www.ory.sh/docs/keto/concepts/subjects) To handle your specific case of nested objects, you would likely need to design a custom permission model using the Ory Permission Language that reflects your resource hierarchy. However, without more context about your specific use case and requirements, it's difficult to provide a more detailed answer. If you need more specific guidance, I recommend reaching out to the Ory community or support channels for tailored advice on implementing this kind of nested object structure in your permission model.bland-finland-95044
01/09/2025, 6:09 PMconst updateBody: UpdateLoginFlowBody = {
method: 'password',
password: password,
identifier: email,
};
await client.updateLoginFlow({
flow: flow.id,
updateLoginFlowBody: updateBody,
});
My ory SDK is configured like this:
this.client = new FrontendApi(
new Configuration({
basePath: process.env.ORY_API_URL,
baseOptions: {
withCredentials: true,
},
})
);
ORY_API_URL is pointed at a local ory tunnel. API login flows against the same tunnel work. I'm getting this error, even after clearing cookies or in a fresh incognito browser
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.
brief-egg-61061
01/09/2025, 6:09 PMbrief-egg-61061
01/09/2025, 6:09 PMupdateLoginFlowBody
. This is likely the primary cause of your error. [Ory API Reference](https://www.ory.sh/docs/reference/api) 3. Handling CSRF Token: You need to extract the CSRF token from the login flow and include it in your request. Here's how you can modify your code: typescript const updateBody: UpdateLoginFlowBody = { method: 'password', password: password, identifier: email, csrf_token: flow.ui.nodes.find( node => node.attributes.name === 'csrf_token' )?.attributes.value || '', }; await client.updateLoginFlow({ flow: flow.id, updateLoginFlowBody: updateBody, });
4. Cookie Handling: Ensure that your Next.js application is correctly handling cookies. The withCredentials: true
in your configuration is correct, but make sure your server is also forwarding the cookies when making requests to Ory. [Ory CSRF troubleshooting](https://www.ory.sh/docs/troubleshooting/csrf) 5. Ory Tunnel: Since you're using Ory Tunnel for local development, make sure it's correctly set up and running. The tunnel should handle CORS issues for you. [Ory Tunnel for local development](https://www.ory.sh/docs/kratos/bring-your-own-ui/custom-ui-basic-integration#debug) 6. Browser Flow vs API Flow: Ensure you're using the correct flow type. Your code suggests you're using a browser flow, which requires different handling compared to an API flow. [Ory API Reference](https://www.ory.sh/docs/reference/api) If you've implemented these changes and are still encountering issues, you might want to: - Double-check that the CSRF token is correctly being passed in the request body. - Ensure that your Ory Tunnel is correctly configured and running. - Try logging the full flow object to see if the CSRF token is present in the UI nodes. - Check your browser's network tab to ensure cookies are being sent and received correctly. If the problem persists after these steps, you may need to debug further by examining the full request and response cycle, or consider reaching out to Ory's support channels for more specific assistance.bland-finland-95044
01/09/2025, 6:15 PMbrief-egg-61061
01/09/2025, 6:15 PMbrief-egg-61061
01/09/2025, 6:15 PMtypescript
import { Configuration, FrontendApi } from "@ory/client"
const frontend = new FrontendApi(
new Configuration({
basePath: "<http://localhost:4000>", // Use your local Ory Tunnel URL
baseOptions: {
withCredentials: true,
},
}),
)
2. Create a login flow:
typescript
import { LoginFlow } from "@ory/client"
import { useEffect, useState } from "react"
function Login() {
const [flow, setFlow] = useState<LoginFlow>()
useEffect(() => {
frontend.createBrowserLoginFlow().then(({ data: flow }) => setFlow(flow))
}, [])
// ... rest of the component
}
3. Render the login form:
typescript
import { UiNodeInputAttributes } from "@ory/client"
import { filterNodesByGroups, isUiNodeInputAttributes } from "@ory/integrations/ui"
function Login() {
// ... previous code
return flow ? (
<form action={flow.ui.action} method={flow.ui.method}>
{filterNodesByGroups({
nodes: flow.ui.nodes,
groups: ["default", "password"],
}).map((node, idx) => {
if (isUiNodeInputAttributes(node.attributes)) {
const attrs = node.attributes as UiNodeInputAttributes
return (
<input
key={idx}
name={attrs.name}
type={attrs.type}
value={attrs.value}
required={attrs.required}
disabled={attrs.disabled}
/>
)
}
})}
<button type="submit">Sign In</button>
</form>
) : (
<div>Loading...</div>
)
}
4. Handle form submission:
typescript
import { AxiosError } from "axios"
import { useRouter } from 'next/router'
function Login() {
// ... previous code
const router = useRouter()
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault()
const form = event.currentTarget
const formData = new FormData(form)
let body = Object.fromEntries(formData) as UpdateLoginFlowBody
try {
await frontend.updateLoginFlow({
flow: flow.id,
updateLoginFlowBody: body,
})
router.push('/') // Redirect to home page on success
} catch (err) {
if (err instanceof AxiosError && err.response?.status === 400) {
// Handle validation errors
setFlow(err.response.data)
} else {
// Handle other errors
console.error(err)
}
}
}
return flow ? (
<form onSubmit={handleSubmit} action={flow.ui.action} method={flow.ui.method}>
{/* ... form fields */}
</form>
) : (
<div>Loading...</div>
)
}
brief-egg-61061
01/09/2025, 6:15 PMtypescript import { Configuration, FrontendApi } from "@ory/client" const frontend = new FrontendApi( new Configuration({ basePath: "<http://localhost:4000>", // Use your local Ory Tunnel URL baseOptions: { withCredentials: true, }, }), )
2. Create a login flow: typescript import { LoginFlow } from "@ory/client" import { useEffect, useState } from "react" function Login() { const [flow, setFlow] = useState<LoginFlow>() useEffect(() => { frontend.createBrowserLoginFlow().then(({ data: flow }) => setFlow(flow)) }, []) // ... rest of the component }
3. Render the login form: typescript import { UiNodeInputAttributes } from "@ory/client" import { filterNodesByGroups, isUiNodeInputAttributes } from "@ory/integrations/ui" function Login() { // ... previous code return flow ? ( <form action={flow.ui.action} method={flow.ui.method}> {filterNodesByGroups({ nodes: flow.ui.nodes, groups: ["default", "password"], }).map((node, idx) => { if (isUiNodeInputAttributes(node.attributes)) { const attrs = node.attributes as UiNodeInputAttributes return ( <input key={idx} name={attrs.name} type={attrs.type} value={attrs.value} required={attrs.required} disabled={attrs.disabled} /> ) } })} <button type="submit">Sign In</button> </form> ) : ( <div>Loading...</div> ) }
4. Handle form submission: typescript import { AxiosError } from "axios" import { useRouter } from 'next/router' function Login() { // ... previous code const router = useRouter() const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault() const form = event.currentTarget const formData = new FormData(form) let body = Object.fromEntries(formData) as UpdateLoginFlowBody try { await frontend.updateLoginFlow({ flow: flow.id, updateLoginFlowBody: body, }) router.push('/') // Redirect to home page on success } catch (err) { if (err instanceof AxiosError && err.response?.status === 400) { // Handle validation errors setFlow(err.response.data) } else { // Handle other errors console.error(err) } } } return flow ? ( <form onSubmit={handleSubmit} action={flow.ui.action} method={flow.ui.method}> {/* ... form fields */} </form> ) : ( <div>Loading...</div> ) }
This implementation covers the basic login flow in Next.js 14 using Ory. It includes creating the login flow, rendering the form, and handling form submission. Remember to handle CSRF protection by including the CSRF token in your form submission, which is automatically included in the flow.ui.nodes
. For more detailed information and advanced use cases, you can refer to the [Ory documentation on custom UI integration](https://www.ory.sh/docs/kratos/bring-your-own-ui/custom-ui-basic-integration).