Docker 20 or later, which is the quickest way to start FusionAuth. (There are other ways.)
While this sample application doesn't have login functionality without FusionAuth, a more typical integration will replace an existing login system with FusionAuth.
In that case, the system might look like this before FusionAuth is introduced.
Request flow during login before FusionAuth
The login flow will look like this after FusionAuth is introduced.
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.
In this section, you’ll get FusionAuth up and running and create a new WordPress application.
First, clone the code from the repository and change into that directory.
git clone https://github.com/FusionAuth/fusionauth-quickstart-wordpress-web.git
cd fusionauth-quickstart-wordpress-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.
If you prefer to copy the files you’ll create in this guide, they already exist in the complete-application
directory.
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.
docker compose up -d
Here you are using a bootstrapping feature of FusionAuth called Kickstart. When FusionAuth comes up for the first time, it will look at the kickstart/kickstart.json
file and configure FusionAuth to your specified state.
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:
E9FDB985-9173-4E01-9D73-AC2D60D1DC8E
.super-secret-secret-that-should-be-regenerated-for-production
.richard@example.com
and the password is password
.admin@example.com
and the password is password
.http://localhost:9011/
.You can log in to the FusionAuth admin UI and look around if you want to, but with Docker and Kickstart, everything will already be configured correctly.
If you want to see where the FusionAuth values came from, they can be found in the FusionAuth app. 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.
The .env
file contains passwords. In a real application, always add this file to your .gitignore
file and never commit secrets to version control.
Next, you’ll set up a basic WordPress site. While this guide builds a new WordPress project, you can use the same method to integrate your existing project with FusionAuth.
If you simply want to run the application, there is a completed version in the complete-application
directory. You can use the following commands to get it up and running if you do not want to create your own.
cd complete-application
docker compose up
Then view the application at the following URL http://localhost:3000.
Browse to http://localhost:3000. It should automatically redirect you to http://localhost:3000/wp-admin/install.php, as this is a brand-new site.
Choose “English (United States)” and click Continue.
On the next page:
Change Bank
.admin
and Password to password
.admin@example.com
.On the success page, click Log In. On the login page, enter the username admin
and password password
and click Log In. (You can return to this page later by browsing to http://localhost:3000/wp-login.php.)
Before you do any FusionAuth work, you’ll create three placeholder pages:
Under Settings -> Permalinks , change Permalink structure to Post name
and click Save Changes. This sets page URLs to be more human-readable than the default numbered URLs.
To add the placeholder pages, first delete the default pages:
Now create new blank pages:
Home
.Account
and one with the title Change
.You now have three blank pages.
Browse to Settings -> Reading . Change Your homepage displays to A static page
and under Homepage select Home
. Save your changes. Now http://localhost:3000 points to your homepage.
Finally, browse to Appearance -> Editor -> Templates -> Blank . Here you are editing the page style template for all three of your new pages. Click on the paragraph (This is the Post Content block ...
) twice to select it. Open the settings menu by clicking the Settings icon to the right of the blue Save button on the top right. On the Block tab and under the Layout section, disable Inner blocks use content width. Click Save and confirm. This changes each page to use the full browser width.
You now have a basic WordPress site with three blank pages. Currently, a user authenticates against the Wordpress user database. Next, you will enable WordPress to use FusionAuth for authentication so that your users can use the same FusionAuth login credentials with this site as any future sites you make or other applications.
On the WordPress dashboard, click Plugins -> Add new . In the search box on the right, paste “OpenID Connect Generic Client”. On the first plugin in the results, by daggerhart, click Install Now, then Activate.
Browse to Settings -> Open ID Connect Client and enter the following settings:
E9FDB985-9173-4E01-9D73-AC2D60D1DC8E
super-secret-secret-that-should-be-regenerated-for-production
openid email profile
http://localhost:9011/oauth2/authorize
http://fusionauth:9011/oauth2/userinfo
http://fusionauth:9011/oauth2/token
http://localhost:9011/oauth2/logout
sub
{email}
(this is what will be displayed to the user in the WordPress admin screen)Requests from the browser will use the endpoint http://localhost:9011
to communicate with the FusionAuth container whilst for container to container communication the internal network name for the FusionAuth container specified in docker compose is fusionauth
so the endpoint http://fusionauth:9011
is used.
Click Save Changes.
Now if you browse to http://localhost:3000/wp-login.php, you can click Login with OpenID Connect and log in on FusionAuth with email richard@example.com
and password password
.
For a simpler user experience, you can remove the option to log in with WordPress. This is an optional step.
Open a terminal and run the following command to overwrite the default wp-login.php
file.
docker cp ./complete-application/wp-login.php fusionauth-quickstart-wordpress-web-wordpress-1:/var/www/html/wp-login.php
The new file starts commenting out the login form on line 1424 with <!--
, and ends the comment on line 1504 with -->
.
Now http://localhost:3000/wp-login.php looks much neater.
Currently, if you log out, you can still browse to the pages that should be restricted, like http://localhost:3000/account
. Let’s prevent that.
At Plugins -> Add New , search for “simple page access restriction” and install and activate the one by Plugins & Snippets. Browse to the plugin settings in the sidebar. Set the following values:
http://localhost:3000/wp-login.php
.Back in Pages , for both the account and change pages, click Edit, enable For Logged-In Users Only at the bottom right, and click Update. Now if you log out and browse to either page, you won’t be able to view it.
The final improvement you can make to the login process is to send the user directly to their account page instead of the dashboard after login.
Search for and install the plugin “Remove Dashboard Access” by TrustedLogin.
Browse to Settings -> Dashboard Access . Change the value of Redirect URL to http://localhost:3000/account
. Click Save Changes.
Now if you log out and log in as richard@example.com
, who is not an administrator, you’ll be redirected to the account page. Log in again as admin@example.com
to continue editing the site.
You now have everything you need to configure FusionAuth authentication on your site. To complete this demonstration application, you’ll add some content to the three blank pages. There are many ways to create custom pages on WordPress, including:
The easiest way to demonstrate the ChangeBank sample pages is to paste custom content into a plugin, but note that is not the most maintainable solution for a real site. If your site is large or complex, take the time to study custom themes and create your own.
For now, search for and add the plugin “WP Coder” by WPCoder.
Browse to Media in the sidebar. Click Add New and select money.jpg
from the complete-application
directory.
Click on the image once it has been uploaded. Copy the “File URL” to use later. It should look like http://localhost:3000/wp-content/uploads/2023/09/money.jpg
.
You’ll now create three shortcodes with the HTML, CSS, and JavaScript for each page.
Browse to WP Coder . Click Add New. In the title box at the top, enter home
. In the HTML Code box, copy and paste the following code.
<div id="page-container">
<div id="page-header">
<div id="logo-header">
<img
src="https://fusionauth.io/cdn/samplethemes/changebank/changebank.svg"
/>
<a class="button-lg" href="/login"> Login </a>
</div>
<div id="menu-bar" class="menu-bar">
<a class="menu-link">About</a>
<a class="menu-link">Services</a>
<a class="menu-link">Products</a>
<a class="menu-link" style="text-decoration-line: underline">Home</a>
</div>
</div>
<div style="flex: 1">
<div class="column-container">
<div class="content-container">
<div style="margin-bottom: 100px">
<h1>Welcome to Changebank</h1>
<p>
To get started,
<a href="/login">log in or create a new account</a>.
</p>
</div>
</div>
<div style="flex: 0">
<img src="http://localhost:3000/wp-content/uploads/2023/09/money-scaled.jpg" style="max-width: 800px" />
</div>
</div>
</div>
</div>
</div>
In the <img src
at the bottom of this code, enter the file URL for the money image you uploaded.
Click the CSS tab, and paste the following code.
h1 {
color: #096324;
}
h3 {
color: #096324;
margin-top: 20px;
margin-bottom: 40px;
}
a {
color: #096324;
}
p {
font-size: 18px;
}
.header-email {
color: #096324;
margin-right: 20px;
}
.fine-print {
font-size: 16px;
}
body {
font-family: sans-serif;
padding: 0px;
margin: 0px;
}
.h-row {
display: flex;
align-items: center;
}
#page-container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
#page-header {
flex: 0;
display: flex;
flex-direction: column;
}
#logo-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
}
.menu-bar {
display: flex;
flex-direction: row-reverse;
align-items: center;
height: 35px;
padding: 15px 50px 15px 30px;
background-color: #096324;
font-size: 20px;
}
.menu-link {
font-weight: 600;
color: #FFFFFF !important;
margin-left: 40px;
}
.menu-link {
font-weight: 600;
color: #FFFFFF !important;
margin-left: 40px;
}
.inactive {
text-decoration-line: none;
}
.button-lg {
width: 150px;
height: 30px;
background-color: #096324;
color: #FFFFFF !important;
font-size: 16px;
font-weight: 700;
border-radius: 10px;
text-align: center;
padding-top: 10px;
text-decoration-line: none;
}
.column-container {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.content-container {
flex: 1;
display: flex;
flex-direction: column;
padding: 60px 20px 20px 40px;
}
.balance {
font-size: 50px;
font-weight: 800;
}
.change-label {
font-size: 20px;
margin-right: 5px;
}
.change-input {
font-size: 20px;
height: 40px;
text-align: end;
padding-right: 10px;
}
.change-submit {
font-size: 15px;
height: 40px;
margin-left: 15px;
border-radius: 5px;
}
.change-message {
font-size: 20px;
margin-bottom: 15px;
}
.error-message {
font-size: 20px;
color: #FF0000;
margin-bottom: 15px;
}
.app-container {
flex: 0;
min-width: 440px;
display: flex;
flex-direction: column;
margin-top: 40px;
margin-left: 80px;
}
.change-container {
flex: 1;
}
Click Save Changes.
Browse to WP Coder . Click Add New. In the title box at the top, enter account
. In the HTML Code box, copy and paste the following code.
<div id="page-container">
<div id="page-header">
<div id="logo-header">
<img src="https://fusionauth.io/cdn/samplethemes/changebank/changebank.svg" />
<div class="h-row">
<p class="header-email">[sv slug="sc-user-email"]</p>
<a class="button-lg" href="/wp-login.php?action=logout"> Logout </a>
</div>
</div>
<div id="menu-bar" class="menu-bar">
<a class="menu-link inactive" href="/change">Make Change</a>
<a class="menu-link" href="/account">Account</a>
</div>
</div>
<div style="flex: 1;">
<div class="column-container">
<div class="app-container">
<h3>Your balance</h3>
<div class="balance">$0.00</div>
</div>
</div>
</div>
</div>
Click the CSS tab, and paste the following code.
h1 {
color: #096324;
}
h3 {
color: #096324;
margin-top: 20px;
margin-bottom: 40px;
}
a {
color: #096324;
}
p {
font-size: 18px;
}
.header-email {
color: #096324;
margin-right: 20px;
}
.fine-print {
font-size: 16px;
}
body {
font-family: sans-serif;
padding: 0px;
margin: 0px;
}
.h-row {
display: flex;
align-items: center;
}
#page-container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
#page-header {
flex: 0;
display: flex;
flex-direction: column;
}
#logo-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
}
.menu-bar {
display: flex;
flex-direction: row-reverse;
align-items: center;
height: 35px;
padding: 15px 50px 15px 30px;
background-color: #096324;
font-size: 20px;
}
.menu-link {
font-weight: 600;
color: #FFFFFF !important;
margin-left: 40px;
}
.menu-link {
font-weight: 600;
color: #FFFFFF !important;
margin-left: 40px;
}
.inactive {
text-decoration-line: none;
}
.button-lg {
width: 150px;
height: 30px;
background-color: #096324;
color: #FFFFFF !important;
font-size: 16px;
font-weight: 700;
border-radius: 10px;
text-align: center;
padding-top: 10px;
text-decoration-line: none;
}
.column-container {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.content-container {
flex: 1;
display: flex;
flex-direction: column;
padding: 60px 20px 20px 40px;
}
.balance {
font-size: 50px;
font-weight: 800;
}
.change-label {
font-size: 20px;
margin-right: 5px;
}
.change-input {
font-size: 20px;
height: 40px;
text-align: end;
padding-right: 10px;
}
.change-submit {
font-size: 15px;
height: 40px;
margin-left: 15px;
border-radius: 5px;
}
.change-message {
font-size: 20px;
margin-bottom: 15px;
}
.error-message {
font-size: 20px;
color: #FF0000;
margin-bottom: 15px;
}
.app-container {
flex: 0;
min-width: 440px;
display: flex;
flex-direction: column;
margin-top: 40px;
margin-left: 80px;
}
.change-container {
flex: 1;
}
Click Save Changes.
Browse to WP Coder . Click Add New. In the title box at the top, enter change
. In the HTML Code box, copy and paste the following code.
<div id="page-container">
<div id="page-header">
<div id="logo-header">
<img
src="https://fusionauth.io/cdn/samplethemes/changebank/changebank.svg"
/>
<div class="h-row">
<p class="header-email">[sv slug="sc-user-email"]</p>
<a class="button-lg" href="/wp-login.php?action=logout"> Logout </a>
</div>
</div>
<div id="menu-bar" class="menu-bar">
<a class="menu-link" href="/change">Make Change</a>
<a class="menu-link inactive" href="/account">Account</a>
</div>
</div>
<div style="flex: 1">
<div class="column-container">
<div class="app-container change-container">
<h3>We Make Change</h3>
<div id="status" class="error-message">
Please enter a dollar amount
</div>
<form>
<div class="h-row">
<div class="change-label" >Amount in USD: $</div>
<input class="change-input" name="amount" value="0.00" id="total" />
<input
class="change-submit"
type="submit"
value="Make Change"
onclick="makeChange(event)"
/>
</div>
</form>
</div>
</div>
</div>
</div>
Click the CSS tab, and paste the following code.
h1 {
color: #096324;
}
h3 {
color: #096324;
margin-top: 20px;
margin-bottom: 40px;
}
a {
color: #096324;
}
p {
font-size: 18px;
}
.header-email {
color: #096324;
margin-right: 20px;
}
.fine-print {
font-size: 16px;
}
body {
font-family: sans-serif;
padding: 0px;
margin: 0px;
}
.h-row {
display: flex;
align-items: center;
}
#page-container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
#page-header {
flex: 0;
display: flex;
flex-direction: column;
}
#logo-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
}
.menu-bar {
display: flex;
flex-direction: row-reverse;
align-items: center;
height: 35px;
padding: 15px 50px 15px 30px;
background-color: #096324;
font-size: 20px;
}
.menu-link {
font-weight: 600;
color: #FFFFFF !important;
margin-left: 40px;
}
.menu-link {
font-weight: 600;
color: #FFFFFF !important;
margin-left: 40px;
}
.inactive {
text-decoration-line: none;
}
.button-lg {
width: 150px;
height: 30px;
background-color: #096324;
color: #FFFFFF !important;
font-size: 16px;
font-weight: 700;
border-radius: 10px;
text-align: center;
padding-top: 10px;
text-decoration-line: none;
}
.column-container {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.content-container {
flex: 1;
display: flex;
flex-direction: column;
padding: 60px 20px 20px 40px;
}
.balance {
font-size: 50px;
font-weight: 800;
}
.change-label {
font-size: 20px;
margin-right: 5px;
}
.change-input {
font-size: 20px;
height: 40px;
text-align: end;
padding-right: 10px;
}
.change-submit {
font-size: 15px;
height: 40px;
margin-left: 15px;
border-radius: 5px;
}
.change-message {
font-size: 20px;
margin-bottom: 15px;
}
.error-message {
font-size: 20px;
color: #FF0000;
margin-bottom: 15px;
}
.app-container {
flex: 0;
min-width: 440px;
display: flex;
flex-direction: column;
margin-top: 40px;
margin-left: 80px;
}
.change-container {
flex: 1;
}
Click on the JS tab, and paste the following code.
function makeChange(event) {
event.preventDefault();
const amount = document.querySelector('#total').value;
const total = Math.trunc(parseFloat(amount) * 100) / 100;
const totalString = isNaN(total) ? '' : total.toFixed(2);
const nickels = Math.floor(total / 0.05);
const nickelsString = nickels.toLocaleString();
const pennies = (total - 0.05 * nickels) / 0.01;
const penniesString = Math.ceil(Math.trunc(pennies * 100) / 100).toLocaleString();
const hasError = !/^(\d+(\.\d*)?|\.\d+)$/.test(amount);
let message = 'Invalid or missing amount';
let css = 'error-message';
if (!hasError) {
message = 'We can make change for ' + totalString + ' with ' + nickelsString + ' nickels and ' + penniesString + ' pennies!';
css = 'change-message';
}
document.querySelector('#status').innerHTML = message;
document.querySelector('#status').className = css;
}
Click Save Changes.
In the list tab of the WP Coder plugin, you can see the shortcodes of each page, like [wp_code id="1"]
. You’ll use these codes to link the custom code to the actual page.
Add the plugin “Snippet Shortcodes” by Ali Colville. This plugin enables the shortcode [sv slug="sc-user-email"]
, which you might have noticed in the HTML of the account and change pages. The shortcode displays the user’s email on the page.
Now you can use these shortcodes on the three pages. Browse to Pages and edit the account page. Click the hamburger menu at the top right and select Code editor. In the text box under the page title box, copy and paste the shortcode associated with account page which should look like [wp_code id="2"]
and click Update.
Go back to the page list and edit the home page. Paste [wp_code id="1"]
and click Update.
Edit the change page, paste [wp_code id="3"]
, and click Update.
Each of your previously blank pages now displays the custom HTML and CSS you added to the WP Coder custom shortcodes.
The demonstration application is now complete. Log out. Verify that you can’t browse to the account page. Log in using richard@example.com
and password
. The make change page will allow you to enter a dollar amount to see how many nickels and pennies you will get.
This quickstart is a great way to get a proof of concept up and running quickly, but to run your application in production, there are some things you're going to want to do.
FusionAuth gives you the ability to customize just about everything to do with the user's experience and the integration of your application. This includes:
Ensure FusionAuth is running in the Docker container. You should be able to log in as the admin user admin@example.com
with a password of password
at http://localhost:9011/admin.
Open the app in an incognito browser window or clear your browser cache and cookies data.
docker compose
command is not found.Ensure you have the latest version of Docker, or try docker-compose
instead. If on Linux, install docker.ce
instead of docker.io
.
Run the following in a terminal.
cd complete-application
docker compose up
Browse to http://localhost:3000 and log in with admin@example.com
and password
.
Now you can look around at the settings and plugins to see how the completed working application differs from yours.