Ory Proxy and Ory Tunnel
The CLI contains two tools that help with local development:
- Ory Proxy
- Ory Tunnel
Before you start using these tools, export the SDK of your project. Run this command:
export ORY_SDK_URL=https://{your-project-slug-here}.projects.oryapis.com
# For a quick way to test, use the playground project:
export ORY_SDK_URL=https://playground.projects.oryapis.com
The main use case for Ory Tunnel and Ory Proxy is local development, but it can also be used in production, on different server types, and in Docker. You can use Ory Tunnel in the same way you use Ory Proxy. Read about the differences between the two at the end of this document.
Ory Tunnel
Ory Tunnel is exposing the Ory APIs under the same top-level domain as your application to ensure that there are no CORS issues.
To run Ory Tunnel, use the ory tunnel
command and point to the URL with your application, for example:
ory tunnel --project $PROJECT_SLUG http://localhost:3000
To get a full list of arguments and options available for use with Ory Tunnel, run: ory tunnel --help
For more details, refer to the Ory Proxy documentation and the differences between Ory Tunnel and Ory Proxy.
Ory Proxy
Ory Proxy is a reverse proxy deployed in front of your application. This allows the Ory endpoints to be mirrored on the same domain as the app you're running.
Ory Proxy rewrites cookies to match the domain your application is currently on. As a result, the origin of the cookies is set to
the domain you run the app on instead of <your-project-slug>.projects.oryapis.com
.
This behavior is necessary to avoid issues with the browsers CORS policy.
Ory Proxy converts sessions into JSON Web Tokens (JWTs) and ensures that cookies and URLs are properly configured.
Using Ory Proxy is an alternative to custom domains (CNAME), and a useful tool when developing locally. In production, it's recommended to use a CNAME.
When an application runs on http://localhost:3000
, Ory must be available on the same domain, for example at
http://localhost:4000
. Thanks to such setup, the system can manage Anti-CSRF Cookies and Ory Session Cookies.
URL structure
Ory Proxy adds /.ory
prefix when mirroring APIs and UIs of Ory Network.
For example, when using the Ory Proxy, calling https://<proxy-host>/.ory/ui/login
is the same as calling
https://<your-project-slug>.projects.oryapis.com/ui/login
directly.
Ory Proxy provides URLs which you can use to start self-service flows:
URL | Self-service Flow |
---|---|
/.ory/self-service/login/browser | Login |
/.ory/self-service/registration/browser | Registration |
/.ory/self-service/recovery/browser | Recovery |
/.ory/self-service/verification/browser | Verification |
/.ory/self-service/settings/browser | Settings |
If you redirect or link the user to one of those paths, the corresponding self-service flow is started, for example:
<a href="/.ory/self-service/login/browser">Log in</a>
You can also append a return_to=<your-url>
query parameter to the URL. This redirects the user to the set URL when they complete
the self-service flow.
<a href="/.ory/self-service/login/browser?return_to=https://localhost:4000/my-url">Log in</a>
The domain used in return_to
must be an allow-listed URL set in the project configuration. The URL must include the protocol and
domain. Relative URLs aren't supported.
Use Ory Proxy for local development
When using Ory Proxy for local development, point to the URL where your application runs.
For example, if your application is available at http://localhost:3000
, run this command:
ory proxy http://localhost:3000
By default, Ory Proxy creates an entry point at http://localhost:4000
. To get access to Ory endpoints, you must access the app
through the proxy using This URL instead of the actual address on which your application is running.
If you want to adjust the entry point URL, pass the desired address along with the application URL, for example:
ory proxy http://localhost:3000 http://localhost:3001
Use Ory Proxy with JSON Web Tokens
Ory Proxy translates known Ory credentials, such as Ory Session Tokens or Ory Session Cookies, to JSON Web Tokens.
When the user calls Ory Proxy with a valid Ory Session Cookie:
GET /some-path
Host: localhost:4000
Cookie: ory_session_jollyproskuriakovaxe98qw5t8g=MTYyNzU1OTgyNHxEdi1CQkFFQ180SUFBUkFCRUFBQVJfLUNBQUVHYzNSeWFXNW5EQThBRFhObGMzTnBiMjVmZEc5clpXNEdjM1J5YVc1bkRDSUFJR3RGU1d4dlUwOXVSR2w1UjJONmFVRlhaWEIxWVhCVlNHWlZOVTQxWWtGMnwhbFZh8BCCQ3tMemDczrB9-epefXl1E7whiChUt62LuA==
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36
...
Ory Proxy resolves the session and converts it to a JSON Web Token. The token is included in the Authorization
HTTP header of
the request made to the application behind Ory Proxy.
The session is also included in the request so that you can use it for example to generate a logout URL.
GET /some-path
Host: <your-application>:3000
Authorization: eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJl...",
Cookie: ory_session_jollyproskuriakovaxe98qw5t8g=MTYyNzU1OTgyNHxEdi1CQkFF...
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko)
it's recommended you to validate the JWT using Ory Proxy's public key. The public key is available at /.ory/proxy/jwks.json
:
curl -sk https://<proxy-host>/.ory/proxy/jwks.json | jq
{
"keys": [
{
"use": "sig",
"kty": "EC",
"kid": "f8f2e6ff-0480-4343-9dee-0d2a463146dc",
"crv": "P-256",
"alg": "ES256",
"x": "Say2LSWvHxUnyxuW5lxsTFkKopZq402eH4YqcRiBgvA",
"y": "7XaYgYsW-Mjb5qIq47LxyaPHjPZfRHRnnfir8aqd9BU"
}
]
}
The token contains all session and identity information linked to the Ory Session Cookie.
This is an example of a JWT with session and identity data:
{
"exp": 1627560124,
"iat": 1627560064,
"iss": "https://<project-slug>.projects.oryapis.com",
"jti": "eaaec243-2cb0-468a-bebe-1a0349242cf0",
"nbf": 1627560064,
"session": {
"id": "b73d7dc4-f565-4fea-951e-8c23ee05783f",
"active": true,
"expires_at": "2021-07-30T12:01:02.96663Z",
"authenticated_at": "2021-07-29T12:01:03.024365Z",
"issued_at": "2021-07-29T12:01:02.966652Z",
"identity": {
"id": "0f0c9bec-6b68-47f3-b62b-7750f065359c",
"schema_id": "default",
"schema_url": "https://<project-slug>.projects.oryapis.com/schemas/default",
"state": "active",
"state_changed_at": "2021-07-29T12:01:02.844472Z",
"traits": {
"email": "dev+docs@ory.sh",
"firstname": "Ory Docs",
"vegetarian": true
},
"verifiable_addresses": [
{
"id": "64b3f270-70fc-48b8-8704-8085c783362b",
"value": "dev+docs@ory.sh",
"verified": false,
"via": "email",
"status": "sent",
"verified_at": null,
"created_at": "2021-07-29T12:01:02.888562Z",
"updated_at": "2021-07-29T12:01:02.888562Z"
}
],
"recovery_addresses": [
{
"id": "526a2b25-2b9a-445b-982d-97862d9bbc9b",
"value": "dev+docs@ory.sh",
"via": "email",
"created_at": "2021-07-29T12:01:02.897407Z",
"updated_at": "2021-07-29T12:01:02.897407Z"
}
],
"created_at": "2021-07-29T12:01:02.877417Z",
"updated_at": "2021-07-29T12:01:02.877417Z"
}
},
"sub": "0f0c9bec-6b68-47f3-b62b-7750f065359c"
}