<@U04UQ68083H> I have a nextjs front end that has ...
# ory-copilot
s
@chilly-king-10285 I have a nextjs front end that has ory auth working on it. It makes some requests to a python backend, on the backend I would like to check and authorise requests based on some data in the public_metadata of the user, how do I do it securely? I am using fastAPI
c
A message from kapa.ai
To secure your backend API and authorize requests based on user data, you can use Ory Oathkeeper. Ory Oathkeeper is a firewall for your backend services and can be used to define access rules for your API endpoints. It can validate various types of tokens such as OAuth 2.0 Access Tokens, JSON Web Tokens, SAML assertions, etc. However, the specific details of how to use Ory Oathkeeper with FastAPI and how to authorize requests based on
public_metadata
of the user are not provided in the given knowledge sources. For more detailed instructions, you may want to refer to the [Ory Oathkeeper documentation](https://github.com/ory/oathkeeper) or reach out to the Ory community on [Ory Community Slack](http://slack.ory.sh/). Please note that the APIs of Ory open-source Servers don't come with integrated access control. This means that all requests sent to their APIs are considered authenticated, authorized, and will be executed. Therefore, it's crucial to protect access to their APIs when deploying Ory open-source Servers. Sources: - [Ory Oathkeeper](https://www.ory.sh/docs/ecosystem/projects#ory-oathkeeper) - [API access control](https://www.ory.sh/docs/self-hosted/operations/api-access-control)
s
@chilly-king-10285 can I somehow read teh cookie that arrives with the request and verify its a valid session?
c
A message from kapa.ai
Yes, you can read the cookie that arrives with the request and verify it's a valid session using Ory's
/sessions/whoami
endpoint. This endpoint uses the HTTP Headers in the GET request to determine who is authenticated. If the credentials are valid, it returns a session object in the body. If the credentials are invalid or no credentials were sent, it returns a
401 Unauthorized
response. Here's a pseudo-code example of how you might do this:
Copy code
python # pseudo-code example @app.get('/protected-endpoint') async def read_item(request: Request):     cookies = request.cookies     session = await client.toSession(undefined, cookies)     print(session)
In this example,
client.toSession
is a method from the Ory Client that checks if a session is valid. It takes two parameters: the session token and the cookies from the request. If the session is valid, it returns the session data. If the session is not valid, it throws an error. Please note that this is a pseudo-code example and may not work out of the box. You'll need to replace
client
with an instance of the Ory Client and
undefined
with the session token if you have one. Sources: - [Ory API Reference - toSession](https://www.ory.sh/docs/reference/api#operation/toSession) - [Check session status](https://www.ory.sh/docs/identities/sign-in/check-session-token-cookie-api)
s
@chilly-king-10285 how can I get the session token in the browser in a nextjs app I am using the FrontendApi
c
A message from kapa.ai
In a Next.js application, you can use the
FrontendApi
from the
@ory/client
package to get the session token. The
toSession
method can be used to check if the user is signed in and has an active session. If the user has an active session, you get a
200 OK
response and the session payload. Here's an example of how you might do this in a React component:
Copy code
jsx import { Configuration, FrontendApi, Session } from "@ory/client"   import { useEffect, useState } from "react"    const ory = new FrontendApi(    new Configuration({    basePath: `https://{project.slug}.<http://projects.oryapis.com|projects.oryapis.com>`,    }),   )    export default function SomeComponent() {    const [session, setSession] = useState<Session | undefined>()      useEffect(() => {     ory     .toSession()     .then(({ data }) => setSession(data))    }, [])     return <div>{session?.id}</div>   }
In this example,
ory.toSession()
is used to get the session data. The session data is then stored in the component's state using the
useState
hook from React. The
useEffect
hook is used to call
ory.toSession()
when the component is first rendered. Please note that this is a simplified example and you might need to adjust it to fit your specific use case. Sources: - [Check session status](https://www.ory.sh/docs/identities/sign-in/check-session-token-cookie-api) - [Session Checks](https://www.ory.sh/docs/kratos/bring-your-own-ui/custom-ui-basic-integration#session-checks)
s
@chilly-king-10285 I have a fastapi backend that needs to allow requests for only users with a valid session, how do I handle that?
c
A message from kapa.ai
To handle requests only from users with a valid session in a FastAPI backend, you can use the Ory Kratos
/sessions/whoami
endpoint to verify the session. This endpoint uses the HTTP Headers in the GET request to determine who is authenticated. If the credentials are valid, it returns a session object in the body. If the credentials are invalid or no credentials were sent, it returns a
401 Unauthorized
response. Here's a pseudo-code example of how you might do this in FastAPI:
Copy code
python from fastapi import FastAPI, Request, HTTPException from ory_kratos_client import Configuration, ApiClient, PublicApi  app = FastAPI()  # Initialize the Ory Kratos API client config = Configuration(     host = "<http://path-to-kratos-public-api>" ) with ApiClient(config) as api_client:     public_api = PublicApi(api_client)  @app.get("/protected-endpoint") async def read_item(request: Request):     # Extract the cookie from the request     cookie = request.cookies.get('ory_kratos_session')      # Call the /sessions/whoami endpoint with the cookie     try:         session = public_api.to_session(cookie=cookie)     except ApiException as e:         if e.status == 401:             raise HTTPException(status_code=401, detail="Unauthorized")         else:             raise HTTPException(status_code=500, detail="Internal server error")      # If the session is valid, continue processing the request     # ...
In this example,
public_api.to_session
is a method from the Ory Kratos Public API that checks if a session is valid. It takes the session cookie as a parameter. If the session is valid, it returns the session data. If the session is not valid, it throws an
ApiException
, which you can catch and handle appropriately. Please note that this is a pseudo-code example and may not work out of the box. You'll need to replace
"<http://path-to-kratos-public-api>"
with the actual URL of your Ory Kratos Public API. Sources: - [Ory API Reference - toSession](https://www.ory.sh/docs/reference/api#operation/toSession) - [Check session status](https://www.ory.sh/docs/identities/sign-in/check-session-token-cookie-api)
s
my request from the front end is not sending the cookie to my backend requests how do I fix that? /* eslint-disable react-hooks/rules-of-hooks */ import { env } from “@/env”; import { useMutation } from “react-query”; const baseUrl = env.NEXT_PUBLIC_API_BASE_URL; const sendInvite = () => { return *useMutation*( async ({ email, org_id }: { email: string; org_id: string }) => { console.*log*(
${baseUrl}/user/invite
,
${baseUrl}/user/invite
); const req = await *fetch*(
${baseUrl}/user/invite
, { method: “POST”, credentials: ‘include’, headers: { “Content-Type”: “application/json; charset=utf-8”, }, body: JSON.*stringify*({ email, org_id, }), // headers: { // “Content-Type”: “application/json”, // }, }); if (req.ok) { return req.*json*(); } console.*error*(“Failed to send invite”, req.status, req.statusText); }, ); }; const user = { sendInvite, }; export const api = { user, };
@chilly-king-10285 my request from the front end is not sending the cookie to my backend requests how do I fix that? /* eslint-disable react-hooks/rules-of-hooks */ import { env } from “@/env”; import { useMutation } from “react-query”; const baseUrl = env.NEXT_PUBLIC_API_BASE_URL; const sendInvite = () => { return *useMutation*( async ({ email, org_id }: { email: string; org_id: string }) => { console.*log*(
${baseUrl}/user/invite
,
${baseUrl}/user/invite
); const req = await *fetch*(
${baseUrl}/user/invite
, { method: “POST”, credentials: ‘include’, headers: { “Content-Type”: “application/json; charset=utf-8”, }, body: JSON.*stringify*({ email, org_id, }), // headers: { // “Content-Type”: “application/json”, // }, }); if (req.ok) { return req.*json*(); } console.*error*(“Failed to send invite”, req.status, req.statusText); }, ); }; const user = { sendInvite, }; export const api = { user, };
c
A message from kapa.ai
Your code seems to be correctly set up to include cookies with the request. You're using
credentials: 'include'
in your fetch options, which should send cookies along with the request. However, there are a few things you need to ensure for the cookies to be sent: 1. Same Domain: Cookies are only sent if the URL of the request is on the same domain as the calling script. If your frontend and backend are on different domains, you'll need to ensure that both are set up to support cross-origin resource sharing (CORS) with credentials. 2. Server Configuration: The server must indicate that it’s okay to expose the credentials to the frontend JavaScript code. This is done by the server including the
Access-Control-Allow-Credentials: true
header in its response. 3. Secure and HttpOnly Flags: If the cookie's
Secure
flag is set, the cookie will only be sent over an encrypted connection. If the
HttpOnly
flag is set, the cookie won't be accessible via JavaScript. These flags can prevent the cookie from being sent with the request in some situations. 4. Browser Settings: Some browser settings or extensions can block cookies. If you're still having issues, you might want to check your browser's Network tab in the developer tools to see if the cookie is being sent with the request. You can also check the server's response headers to see if the
Set-Cookie
header is present and correctly configured. Sources: - [Cross-Origin HTTP cookies](https://www.ory.sh/docs/security-model#cross-origin-http-cookies) - [Accessing APIs from client-side JavaScript / AJAX](https://www.ory.sh/docs/troubleshooting/csrf#accessing-apis-from-client-side-javascript--ajax) - [Session Checks](https://www.ory.sh/docs/kratos/bring-your-own-ui/custom-ui-basic-integration#session-checks)
s
@chilly-king-10285 in python how do I update a users metadata? also is there a way to edit a users metadata in in the ui?
c
A message from kapa.ai
To update a user's metadata in Python, you can use the Ory Kratos Admin API. Specifically, you can use the
updateIdentity
method of the
AdminApi
class. This method takes two parameters: the ID of the identity you want to update and an
UpdateIdentity
object that contains the new metadata. Here's a pseudo-code example of how you might do this:
Copy code
python from ory_kratos_client import Configuration, ApiClient, AdminApi, UpdateIdentity  # Initialize the Ory Kratos API client config = Configuration(     host = "<http://path-to-kratos-admin-api>" ) with ApiClient(config) as api_client:     admin_api = AdminApi(api_client)  # Define the new metadata new_metadata = {     "metadata_public": {         "key": "new value"     },     "metadata_admin": {         "key": "new value"     } }  # Create an UpdateIdentity object update_identity = UpdateIdentity(**new_metadata)  # Update the identity admin_api.update_identity("identity-id", update_identity)
In this example, replace
"<http://path-to-kratos-admin-api>"
with the actual URL of your Ory Kratos Admin API,
"identity-id"
with the actual ID of the identity you want to update, and
"key"
and
"new value"
with the actual keys and values you want to update. Please note that this is a pseudo-code example and may not work out of the box. You'll need to adjust it to fit your specific use case. As for updating a user's metadata in the UI, the Ory Kratos Self-Service UI does not currently support updating metadata directly. The only way to update the metadata is to use the
/admin/identities
APIs. Sources: - [Identity metadata & traits](https://www.ory.sh/docs/kratos/manage-identities/managing-users-identities-metadata) - [Update identity metadata](https://www.ory.sh/docs/guides/integrate-with-ory-cloud-through-webhooks#update-identity-metadata) - [Ory API Reference - updateIdentity](https://www.ory.sh/docs/reference/api#operation/updateIdentity)
s
@chilly-king-10285 what is ory kratos is it different than the ory sdk?
c
A message from kapa.ai
Yes, Ory Kratos and Ory SDK are different but related components of the Ory ecosystem. Ory Kratos is an open-source identity and user management system. It provides features like self-service login and registration, multi-factor authentication, account verification, account recovery, profile and account management, and admin APIs. It is designed to be API-first and follows cloud architecture best practices. Ory Kratos can be used to secure and manage user identities, permissions, and access to resources in your applications and APIs. It can be hosted on any operating system and scales horizontally without effort. [source](https://www.ory.sh/docs/kratos/ory-kratos-intro) On the other hand, Ory SDK is a set of software development kits that allow for integration with Ory services, including Ory Identities (Kratos), Ory Permissions (Keto), and Ory OAuth2. The SDKs are generated using the openapi-generator and are available for popular programming languages like Dart, .NET, Elixir, Go, Java, JavaScript, PHP, Python, Ruby, and Rust. The SDKs provide a convenient way to interact with the Ory APIs in your preferred programming language. [source](https://www.ory.sh/docs/sdk) In summary, Ory Kratos is the identity and user management system, while Ory SDK is a set of tools that help you interact with Ory services, including Kratos, in your applications.
s
@chilly-king-10285 what is the identity and user management system? what does that do exactly?
c
A message from kapa.ai
An Identity and User Management System, like Ory Kratos, is a set of tools and protocols used to manage and secure user identities and access to resources in applications and APIs. It provides a structured way to create, manage, and authenticate users, and control their access to resources. Here's what it does: 1. User Registration and Authentication: It allows users to create accounts (register) and verify their identities (login). This can be done using various methods such as username/email and password combinations, social sign-in (like "Sign in with Google, GitHub"), or passwordless flows. 2. Multi-factor Authentication (MFA): It provides additional layers of security by requiring users to provide at least two forms of identification before they can access their accounts. 3. Account Verification: It verifies that an email address, phone number, or physical address actually belongs to the user who registered the account. 4. Account Recovery: It provides mechanisms for users to recover access to their accounts if they forget their passwords or lose access to their accounts. 5. Profile and Account Management: It allows users to securely update their profiles, change passwords, manage personal details, email addresses, and linked social profiles. 6. Session Management: It manages user sessions to keep users signed in and track their interactions with the application. 7. Admin APIs: It provides APIs for administrators to import, update, and delete user accounts. 8. Customization: It allows you to fully customize your users' experience, including customizing the registration process, login process, and user profile management. In the case of Ory Kratos, it implements all these features in a secure and straightforward way, allowing developers to focus on building their applications without worrying about implementing these complex and critical functionalities from scratch. [source](https://www.ory.sh/docs/kratos/ory-kratos-intro)
s
@chilly-king-10285 where do I import JsonPatch from? in python?
c
A message from kapa.ai
The
JsonPatch
class is not directly mentioned in the provided knowledge sources. However, in the context of Ory and Python, it's likely that
JsonPatch
refers to a JSON Patch document, which is a format for describing changes to a JSON document. It's used in various Ory APIs to update resources. In Python, you can create a JSON Patch document as a regular Python dictionary or list. Here's an example:
Copy code
python patch = [     {         "op": "replace",         "path": "/name",         "value": "New name"     } ]
In this example,
patch
is a JSON Patch document that describes a change to replace the value of the
name
field with
"New name"
. If you need to apply a JSON Patch document to a JSON document, you can use the
jsonpatch
library in Python. Here's an example:
Copy code
python import jsonpatch  # Original JSON document doc = {     "name": "Old name" }  # JSON Patch document patch = [     {         "op": "replace",         "path": "/name",         "value": "New name"     } ]  # Apply the patch new_doc = jsonpatch.apply_patch(doc, patch)  print(new_doc)  # Prints: {"name": "New name"}
In this example,
jsonpatch.apply_patch
is used to apply the
patch
to
doc
. The result is a new JSON document with the changes applied. Please note that this is a general explanation of how JSON Patch works in Python and may not apply directly to your use case with Ory. For more specific instructions, you may want to refer to the [Ory documentation](https://www.ory.sh/docs/) or the [Python
jsonpatch
library documentation](https://python-json-patch.readthedocs.io/en/latest/).
s
@chilly-king-10285 documentation on how to update the user metadata
c
A message from kapa.ai
To update a user's metadata in Ory Kratos, you can use the Admin API's
updateIdentity
method. This method allows you to update the metadata of an identity. Here's a Python example using the Ory Kratos Client:
Copy code
python from ory_kratos_client import Configuration, ApiClient, AdminApi, UpdateIdentity  # Initialize the Ory Kratos API client config = Configuration(     host = "<http://path-to-kratos-admin-api>" ) with ApiClient(config) as api_client:     admin_api = AdminApi(api_client)  # Define the new metadata new_metadata = {     "metadata": {         "metadata_public": {             "key": "new value"         },         "metadata_admin": {             "key": "new value"         }     } }  # Create an UpdateIdentity object update_identity = UpdateIdentity(**new_metadata)  # Update the identity admin_api.update_identity("identity-id", update_identity)
In this example, replace
"<http://path-to-kratos-admin-api>"
with the actual URL of your Ory Kratos Admin API,
"identity-id"
with the actual ID of the identity you want to update, and
"key"
and
"new value"
with the actual keys and values you want to update. Please note that this is a pseudo-code example and may not work out of the box. You'll need to adjust it to fit your specific use case. As for updating a user's metadata in the UI, the Ory Kratos Self-Service UI does not currently support updating metadata directly. The only way to update the metadata is to use the
/admin/identities
APIs. Sources: - [Identity metadata & traits](https://www.ory.sh/docs/kratos/manage-identities/managing-users-identities-metadata) - [Update identity metadata](https://www.ory.sh/docs/guides/integrate-with-ory-cloud-through-webhooks#update-identity-metadata) - [Ory API Reference - updateIdentity](https://www.ory.sh/docs/reference/api#operation/updateIdentity)
s
@chilly-king-10285 documentation on how to update the user public_metadata
c
A message from kapa.ai
To update a user's public metadata in Ory Kratos, you can use the Admin API's
updateIdentity
method. This method allows you to update the metadata of an identity. Here's a Python example using the Ory Kratos Client:
Copy code
python from ory_kratos_client import Configuration, ApiClient, AdminApi, UpdateIdentity  # Initialize the Ory Kratos API client config = Configuration(     host = "<http://path-to-kratos-admin-api>" ) with ApiClient(config) as api_client:     admin_api = AdminApi(api_client)  # Define the new metadata new_metadata = {     "metadata": {         "metadata_public": {             "key": "new value"         }     } }  # Create an UpdateIdentity object update_identity = UpdateIdentity(**new_metadata)  # Update the identity admin_api.update_identity("identity-id", update_identity)
In this example, replace
"<http://path-to-kratos-admin-api>"
with the actual URL of your Ory Kratos Admin API,
"identity-id"
with the actual ID of the identity you want to update, and
"key"
and
"new value"
with the actual keys and values you want to update. Please note that this is a pseudo-code example and may not work out of the box. You'll need to adjust it to fit your specific use case. As for updating a user's metadata in the UI, the Ory Kratos Self-Service UI does not currently support updating metadata directly. The only way to update the metadata is to use the
/admin/identities
APIs. Sources: - [Identity metadata & traits](https://www.ory.sh/docs/kratos/manage-identities/managing-users-identities-metadata) - [Update identity metadata](https://www.ory.sh/docs/guides/integrate-with-ory-cloud-through-webhooks#update-identity-metadata) - [Ory API Reference - updateIdentity](https://www.ory.sh/docs/reference/api#operation/updateIdentity)