Protect a Page with Login in React
This guide shows how to create a simple React application and secure access to the app with Ory. You can use this guide with both Ory Cloud and self-hosted Ory software.
This guide is perfect for you if:
- You have React installed.
- You want to build an app using React.
- You want to give access to your application to signed-in users only.
Before you start, watch this video to see the user flow you're going to implement:
info
You can find the code of the sample application here.
Create React App
First we create a new React project:
npx create-react-app --typescript my_project
cd my_project
Install Ory SDK
Use npm
to install the Ory SDK:
npm i --save @ory/client
Require Login to Access the App Page
Next we add a session check to the default home page of the React example application.The highlighted code is what we added to check whether the user is signed in, get the logout url flow and redirect them to the login page if not. There is also a welcome message with the registered user email and a logout link:
import React, { useEffect, useState } from 'react'
import logo from './logo.svg'
import './App.css'
import { V0alpha2Api, Configuration, Session, Identity } from '@ory/client'
function App() {
const [session, setSession] = useState<Session | undefined>()
const [logoutUrl, setLogoutUrl] = useState<string | undefined>()
// Get your Ory url from .env
// Or localhost for local development
const basePath = process.env.REACT_APP_ORY_URL || "http://localhost:4000"
const ory = new V0alpha2Api(
new Configuration({
basePath,
baseOptions: {
withCredentials: true,
},
})
)
// Returns either the email or the username depending on the user's Identity Schema
const getUserName = (identity: Identity) =>
identity.traits.email || identity.traits.username
// Second, gather session data, if the user is not logged in, redirect to login
useEffect(() => {
ory
.toSession()
.then(({ data }) => {
// User has a session!
setSession(data)
ory.createSelfServiceLogoutFlowUrlForBrowsers().then(({ data }) => {
// Get also the logout url
setLogoutUrl(data.logout_url)
})
})
.catch(() => {
// Redirect to login page
window.location.replace(`${basePath}/ui/login`)
})
})
if (!session) {
// Still loading
return <h1>Loading...</h1>
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Welcome to Ory,{' '}
{
getUserName(session?.identity)
}
.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
{
// Our logout link
<a href={logoutUrl}>Logout</a>
}
</header>
</div>
)
}
export default App
Run Ory APIs on localhost
The Ory security model uses HTTP cookies to manage sessions, tokens, and cookies. To do that, Ory APIs must be exposed on the same domain as your application.
In the case of this example, the domain of your application, which runs on your local machine, is localhost
.
info
When developing locally, use either localhost
or 127.0.0.1
, but not both. Although technically these mean the same thing,
they're different hostnames.
Using both interchangeably in your code can cause problems with the origin of HTTP cookies sent by the application. When that happens Ory APIs might not be able to read the cookies sent by your app.
To get your application that runs locally and Ory APIs on the same domain, use Ory Tunnel - a development tool bundled with Ory CLI. It's like a microservice - an authentication API server on your domain!
npx @ory/cli tunnel --dev http://localhost:3000
Ory APIs are now mirrored on http://localhost:4000
. Use that URL as the baseUrl
for the @ory/client
SDK (see code above).
The --dev
flag disables security checks for easier integration and should not be used when deploying the Tunnel
to a staging environment.
Run your React App
Great, that's it! Let's run your application! Set up your environment variables to connect with Ory's APIs
- macOS
- Linux
- Windows CMD
- Windows Powershell
- Self-Hosted Ory Kratos
# This is a public Ory Cloud Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up for Ory Cloud at
#
# https://console.ory.sh/registration
#
# and create a free Ory Cloud Project to see your own configuration embedded in code samples!
export ORY_SDK_URL=https://{your-project-slug-here}.projects.oryapis.com
# This is a public Ory Cloud Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up for Ory Cloud at
#
# https://console.ory.sh/registration
#
# and create a free Ory Cloud Project to see your own configuration embedded in code samples!
export ORY_SDK_URL=https://{your-project-slug-here}.projects.oryapis.com
# This is a public Ory Cloud Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up for Ory Cloud at
#
# https://console.ory.sh/registration
#
# and create a free Ory Cloud Project to see your own configuration embedded in code samples!
set ORY_SDK_URL=https://{your-project-slug-here}.projects.oryapis.com
# This is a public Ory Cloud Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up for Ory Cloud at
#
# https://console.ory.sh/registration
#
# and create a free Ory Cloud Project to see your own configuration embedded in code samples!
$Env:ORY_SDK_URL = "https://{your-project-slug-here}.projects.oryapis.com"
Clone and run Ory Kratos locally
git clone --depth 1 --branch master https://github.com/ory/kratos.git
cd kratos
git checkout master
git pull -ff
docker-compose -f quickstart.yml -f contrib/quickstart/kratos/cloud/quickstart.yml up --build --force-recreate -d
and set the environment variable to the exposed port:
export ORY_SDK_URL=http://localhost:4433
and start the React development server:
npm run start
Then open http://localhost:3000 in your browser. After loading, you now are presented with Ory's Sign In page! Let's click on sign up and create your first user!
Go to Production
To promote this app to production:
- Build the React app and run it somewhere (for example on Vercel or Netlify)
- Deploy the API (for example, on Heroku)
- Connect your project with a custom domain
These three components must be hosted on the same top-level domain as they were on your local machine:
Component | Production | Local |
---|---|---|
Single Page App | www.example.org | localhost:3000 |
Ory | ory.example.org | localhost:4000 |