# FusionAuth QuickStart for PHP QuickStart integration of PHP web application with FusionAuth. > For the index of this section of the site, see [llms.txt](https://4002.18-224-161-104.sslip.io/docs/llms.txt)  In this QuickStart, you are going to build an application with PHP and integrate it with FusionAuth. You'll be building it for [ChangeBank](https://www.youtube.com/watch?v=CXDxNCzUspM), a global leader in converting dollars into coins. It'll have areas reserved for users who have logged in as well as public facing sections. The Docker Compose file and source code for a complete application are available at [https://github.com/FusionAuth/fusionauth-quickstart-php-web](https://github.com/FusionAuth/fusionauth-quickstart-php-web). Note When developing PHP web applications, it's advisable to consider using a framework. Frameworks provide a structured environment, streamlining development and enhancing code organization. With built-in security features, community support, and time-saving tools, frameworks offer a robust foundation for efficient and maintainable projects. ## Prerequisites For this QuickStart, you'll need: * [PHP](https://www.php.net/downloads.php) 8.1+ * [Composer](https://getcomposer.org/) * [Docker](https://www.docker.com) version 20 or later, which is the quickest way to start FusionAuth. (There are [other ways](https://4002.18-224-161-104.sslip.io/docs/get-started/download-and-install.md).) ## General Architecture Here's a typical application login flow before FusionAuth: ```mermaid sequenceDiagram participant User participant App as Application User ->> App : View Homepage User ->> App : Click Login Link App ->> User : Show Login Form User ->> App : Fill Out and Submit Login Form App ->> App : Authenticates User App ->> User : Display User's Account or Other Info ``` Request flow during login before FusionAuth And here's the same application login flow after introducing FusionAuth: ```mermaid sequenceDiagram participant User participant App as Application participant FusionAuth User ->> App : View Homepage User ->> App : Click Login Link (to FusionAuth) User ->> FusionAuth : View Login Form FusionAuth ->> User : Show Login Form User ->> FusionAuth : Fill Out and Submit Login Form FusionAuth ->> FusionAuth : Authenticates User FusionAuth ->> User: Go to Redirect URI User ->> App: Request the Redirect URI App ->> FusionAuth : Is User Authenticated? FusionAuth ->> App : User is Authenticated App ->> User : Display User's Account or Other Info ``` Request flow during login after FusionAuth In general, you are introducing FusionAuth in order to normalize and consolidate user data. This helps make sure it is consistent and up-to-date as well as offloading your login security and functionality to FusionAuth. ## Getting Started Start with getting FusionAuth up and running and creating a new PHP application. ### Clone The Code First, grab the code from the repository and change to that directory. ```shell-session $ git clone https://github.com/FusionAuth/fusionauth-quickstart-php-web.git ``` ```shell-session $ cd fusionauth-quickstart-php-web ``` All shell commands in this guide can be entered in a terminal in this directory. On Windows, you need to replace forward slashes with backslashes in paths. All the files you'll create in this guide already exist in the `complete-application` subdirectory, if you prefer to copy them to your application. ### Run FusionAuth Via Docker You'll find a Docker Compose file (`docker-compose.yml`) and an environment variables configuration file (`.env`) in the root directory of the repo. Assuming you have Docker installed, you can stand up FusionAuth on your machine with the following. ```shell-session $ docker compose up -d ``` Here you are using a bootstrapping feature of FusionAuth called [Kickstart](https://4002.18-224-161-104.sslip.io/docs/get-started/download-and-install/development/kickstart.md). When FusionAuth comes up for the first time, it will look at the `kickstart/kickstart.json` file and configure FusionAuth to your specified state. Note If you ever want to reset the FusionAuth application, you need to delete the volumes created by Docker Compose by executing `docker compose down -v`, then re-run `docker compose up -d`. FusionAuth will be initially configured with these settings: * Your client Id is `e9fdb985-9173-4e01-9d73-ac2d60d1dc8e`. * Your client secret is `super-secret-secret-that-should-be-regenerated-for-production`. * Your example username is `richard@example.com` and the password is `password`. * Your admin username is `admin@example.com` and the password is `password`. * The base URL of FusionAuth is `http://localhost:9011/`. You can log in to the [FusionAuth admin UI](http://localhost:9011/admin) and look around if you want to, but with Docker and Kickstart, everything will already be configured correctly. Note If you want to see where the FusionAuth values came from, they can be found in the [FusionAuth app](http://localhost:9011/admin). The tenant Id is found on the Tenants page. To see the Client Id and Client Secret, go to the Applications page and click the `View` icon under the actions for the ChangeBank application. You'll find the Client Id and Client Secret values in the `OAuth configuration` section. Caution The `.env` file contains passwords. In a real application, always add this file to your `.gitignore` file and never commit secrets to version control. ### The Basic PHP Application While this guide builds a new PHP project, you can use the same method to integrate your existing project with FusionAuth. Note If you simply want to run the application and not create your own, there is a completed version in the `complete-application` directory. You can use the following commands to get it up and running. ```shell-session $ cd complete-application && \ composer install && \ php -S localhost:9012 -t public ``` View the application at [http://localhost:9012](http://localhost:9012). First create the directory for your application and change to that directory. ```bash mkdir your-application cd your-application ``` Before you start coding, you need to install the PHP module for your application to communicate with FusionAuth. Run the following command. ```bash composer require vlucas/phpdotenv jerryhopper/oauth2-fusionauth ``` ## Authentication Authentication in PHP is managed by [FusionAuth community member Jerry Hopper's FusionAuth Provider](https://github.com/jerryhopper/oauth2-fusionauth) for [The League's OAuth library](https://github.com/thephpleague/oauth2-client). Create an `.env` file within `your-application` directory and insert the following lines. ```shell FUSIONAUTH_CLIENT_ID="e9fdb985-9173-4e01-9d73-ac2d60d1dc8e" FUSIONAUTH_CLIENT_SECRET="super-secret-secret-that-should-be-regenerated-for-production" FUSIONAUTH_SERVER_URL="http://localhost:9011" FUSIONAUTH_BROWSER_URL="http://localhost:9011" FUSIONAUTH_REDIRECT_URL="http://localhost:9012/login.php" ``` This tells PHP where to find and connect to FusionAuth. In this application authentication is handled by two files: `login.php` and `logout.php`. The login file is based almost exactly on Jerry Hopper's code, but is split into neater functions and does two extra things: Starts a session and saves the user details to the session after login. Create a `public` directory within `your-application`. ```shell-session $ mkdir public ``` In the `public` directory, create a `login.php` file and insert the following code. ```php load(); } function startSafeSession() { $cookieParams = [ 'lifetime' => 0, // 0 means "until the browser is closed" 'path' => '/', // entire site can use this cookie // 'domain' => '', // Set your domain here 'secure' => false, // true for HTTPS, false for HTTP 'httponly' => true, // true to make the cookie accessible only through the HTTP protocol 'samesite' => 'Strict' // None, Lax, or Strict ]; session_set_cookie_params($cookieParams); session_start(); } function getFusionAuthProvider(): object { $fusionAuthClientId = $_ENV['FUSIONAUTH_CLIENT_ID'] ?? getenv('FUSIONAUTH_CLIENT_ID'); $fusionAuthClientSecret = $_ENV['FUSIONAUTH_CLIENT_SECRET'] ?? getenv('FUSIONAUTH_CLIENT_SECRET'); $fusionAuthServerUrl = $_ENV['FUSIONAUTH_SERVER_URL'] ?? getenv('FUSIONAUTH_SERVER_URL'); $fusionAuthBrowserUrl = $_ENV['FUSIONAUTH_BROWSER_URL'] ?? getenv('FUSIONAUTH_BROWSER_URL'); $fusionAuthRedirectUrl = $_ENV['FUSIONAUTH_REDIRECT_URL'] ?? getenv('FUSIONAUTH_REDIRECT_URL'); $provider = new \JerryHopper\OAuth2\Client\Provider\FusionAuth([ 'clientId' => $fusionAuthClientId, 'clientSecret' => $fusionAuthClientSecret, 'redirectUri' => $fusionAuthRedirectUrl, 'urlAuthorize' => $fusionAuthBrowserUrl . '/oauth2/authorize', 'urlAccessToken' => $fusionAuthServerUrl . '/oauth2/token', 'urlResourceOwnerDetails' => $fusionAuthServerUrl . '/oauth2/userinfo', ]); return $provider; } function redirectToAccountPageIfAlreadyLoggedIn() { if (isset($_SESSION['id'])) { header('Location: account.php'); exit; } } function redirectUserToFusionAuthIfNotLoggedIn($provider) { if (isset($_GET['code'])) return; $options = [ 'scope' => ['openid email profile'] ]; $authUrl = $provider->getAuthorizationUrl($options); $_SESSION['oauth2state'] = $provider->getState(); header('Location: '.$authUrl); exit; } function checkCSRFToken() { if (empty($_GET['state']) || (!\hash_equals($_SESSION['oauth2state'], $_GET['state']))) { unset($_SESSION['oauth2state']); exit('Invalid CSRF state'); } } function handleFusionAuthCallback($provider) { $token = $provider->getAccessToken('authorization_code', ['code' => $_GET['code']]); try { $user = $provider->getResourceOwner($token); $userArray = $user->toArray(); $email = $user->getEmail(); $name = $userArray['given_name']; session_regenerate_id(); $_SESSION['id'] = $user->getId(); $_SESSION['email'] = $email; $_SESSION['name'] = $name; header('Location: account.php'); } catch (Exception $e) { exit('Failed to get user details from FusionAuth'); } } ``` This setup code: * Prevents errors from being displayed in the browser, for security. * Loads all vendor modules into PHP so you can use them. * Reads your variables from the `.env` file. * Starts a new session using HTTP (not HTTPS since you're on localhost) and ensures your user Id cookie will not be accessible by JavaScript. Next comes the FusionAuth handlers. Starting from the `getFusionAuthProvider()` function, the code: * Creates a FusionAuth provider with your environment variables. * Sends the user to the account page if they already have a login cookie. * Sends the user to the FusionAuth URL if they are not logged in. * Checks the user's FusionAuth token if they are not logged in but are returning from FusionAuth. * Gets the user details from the FusionAuth token and saves them to the server-side session. This also generates a new session or cookie Id for the user for security. The user is then redirected to their account page. PHP automatically links the user's session to their browser by returning a cookie for the site, which is then included in every subsequent request. The login page handles both the initial user request to start the login process and the server callback request from FusionAuth to complete the authentication. Logging out is much simpler. Create a `logout.php` file in the `public` directory and insert the following code. ```php
To get started, log in or create a new account.