Protect a Page with Login in PHP
This guide shows how to create a simple PHP 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 PHP installed.
- You want to build an app using PHP.
- 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 PHP App
First we create a new PHP project:
mkdir your-project
cd your-project
touch index.php
Install Dependencies
To interact with Ory's APIs we install the Ory SDK:
composer require ory/client:^v0.0.1-alpha
To simplify URLs handling we install the bramus/router
composer require bramus/router
To install Ory CLI follow this guide
Why do I Need the Ory CLI?
The Ory CLI includes useful functionality to manage your Ory Cloud Project. But that is not why we require it in this guide!
Ory's philosophy is to make hard things easy for you. For this reason, Ory has deployed measures against all OWASP Top 10 and implements the OWASP Authentication Cheat Sheet along other mechanisms.
Therefore, Ory manages Anti-CSRF Cookies as well as Ory Session Cookies for you. That however requires that Ory and your application run on the same domain!
If your application runs on http://localhost:3000
then Ory needs to be
available on the hostname localhost
as well (e.g. http://localhost:3001
).
That is why we need the Ory CLI, because it has a proxy included which mirrors
Ory's API endpoints on the domain of your application.
Create an Entry Page
This is a working example of basic index.php
script which creates an Ory
client, registers new route for our Dashboard and makes use of
Before Route Middlewares
to validate if the user is allowed to view the Dashboard.
<?php
require 'vendor/autoload.php';
require_once 'app.php';
error_reporting(E_ERROR | E_PARSE);
$proxyPort = getenv("PROXY_PORT");
if ($proxyPort == "") $proxyPort = "4000";
$app = new App;
// register a new Ory client with the URL set to the Ory CLI Proxy
// we can also read the URL from the env or a config file
$config = Ory\Client\Configuration::getDefaultConfiguration()->setHost(sprintf("http://localhost:%s/.ory", $proxyPort));
$app->ory = new Ory\Client\Api\V0alpha2Api(new GuzzleHttp\Client(), $config);
$router = new \Bramus\Router\Router();
$router->before('GET', '/', $app->validateSession());
$router->get('/', $app->printDashboard());
$router->run();
?>
Validate and Login
Next we will create handler which will check with your Ory project if the user
has a valid session. Notice here that we are taking the current request
cookies and passing them along to the Ory client.
If the session is not valid the request is redirected to the Ory project for login. At this point we have not set up any custom UI management and thus will be shown the Ory Managed UI login page.
For the last part we need to add the Dashboard handler (the page we would like to protect) which will render an HTML with the session data.
This is accomplished by the simple App
class stored in the app.php
file:
<?php
class App {
// save the session to display it on the dashboard
private ?Ory\Client\Model\Session $session;
public ?Ory\Client\Api\V0alpha2Api $ory;
public function validateSession(){
$cookies = "";
// set the cookies on the ory client
foreach ($_COOKIE as $key=>$value) {
$cookies .= "$key=$value;";
}
try {
// check if we have a session
$session = $this->ory->toSession("", $cookies);
if (! $session["active"]) throw new Exception('Session expired');
} catch (Exception $e) {
error_log('Exception when calling V0alpha2Api->toSession: '.$e->getMessage());
// this will initialize a new login flow and Kratos will redirect the user to the login UI
header("Location: /.ory/api/kratos/public/self-service/login/browser", true, 303);
die();
}
$this->session = $session;
}
public function printDashboard(){
echo '
<html lang="en">
<head>
<title>Ory Cloud secured Go web app</title>
</head>
<body>
<h1>Dashboard</h1>
<hr />
<h2>Your Session Data:</h2>
<pre><code>', json_encode($this->session, JSON_PRETTY_PRINT), '</code></pre>
</body>
</html>
';
}
}
?>
Run your App
Start your HTTP server and access the proxy URL
php -S 127.0.0.1:3000
- 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
ory proxy http://localhost:3000
To access the PHP app through the ORY proxy open http://localhost:4000 in your browser. You are presented with Ory's Sign In page! Let's click on sign up and create your first user!
Go to Production
Going to production with your app is possible in many ways. Whether you deploy
it on Kubernetes, AWS, a VM, or a RaspberryPi is up to you. To get your app
working with Ory, your app and Ory must be available under the same common
domain (e.g. https://ory.example.com
and https://www.example.com
).
The easiest way to connect Ory to your domain is to connect Ory to a subdomain of yours. You can do this easily by adding a Custom Domain to your Cloud project!
With the custom domain set up, you do not need the Ory Proxy anymore and will use the configured custom domain in your SDK calls:
$config = Ory\Client\Configuration::getDefaultConfiguration()->setHost("https://ory.example.org"));
$ory = new Ory\Client\Api\V0alpha2Api(new GuzzleHttp\Client(), $config);