Without the PHP, Date() is called with no arguments and returns the current time according to the web browser, i.e. according to the laptop’s system clock. With the PHP, Date() is called with "milliseconds since 1970 according to the server’s clock”. The PHP Hypertext Processor will pass through the HTML unmodified until it detects the <?php … ?> tag, which it will replace with the output of the PHP program.
The timedemo website is protected with HTTP Basic Authentication. A username and password are required to access it. Let’s review how HTTP Basic Authentication works. We looked at a diagram from dailysecurity.net. But suppose we don’t want the timedemo website to know which users are allowed to access it, or their passwords. In fact, we want the authentication checking to be completely separate, on a different server. Let’s discuss how OAuth2 authentication works. We looked at a diagram, from websequencediagrams.com.
A customer has requested that Quoin develop an authentication service. We decided to use OAuth2. The authorization server will be in Java using the Spring framework. And the websites requiring authentication will be written (by customer employees) in PHP using the CodeIgniter framework.
Let’s glance over the CodeIgniter framework to see how support for OAuth2 can be added to a PHP application that was developed using CodeIgniter. And let’s make a sample website, using PHP and CodeIgniter, which requires OAuth2 authentication. We can add a small hook to the main Controller which will, for every request, call an “authenticate_if_needed” function. We can separate our work into the “phpauthdemo” module which is the example app, and the “authentication” module which can be reused in the customer’s app. And since the Java-based authentication server is not ready yet, we will implement our own authentication server in PHP, as the “authserverstub” module. Writing both sides of the protocol does make it easier to understand what’s going on, and to discover potential issues.
The authserverstub can take some shortcuts, such as accepting any username provided that the password “opensesame” is entered, and using transparent reusable strings for the authentication codes, instead of opaque values which can only be used once. OAuth2 allows us to use tokens in whatever format we like. We decided to use JSON Web Tokens. We decided to sign the tokens so that they can be verified for acceptance without needing to ask the authorization server if they’re good. For signing and verification we use the Halite PHP library, which is on top of libsodium. The keys are stored in JSON Web Key format. The phpauthdemo and authserverstub are running on CentOS virtual machines on the presenter’s MacBook. When a page of the phpauthdemo is accessed that requires authentication, the user is redirected to the login screen on the other virtual machine, and then redirected back after a successful login.
Note how the authentication library validates the tokens for every HTTP request, even if the user is accessing a page that does not require authentication, because it is useful for the app to know, even on unauthenticated pages, if there is an authenticated user. The app has a “status” endpoint so that JavaScript can inquire who is authenticated, and for how much longer. The app has a “poke” button to initiate an AJAX request. This demonstrates that when you are performing an AJAX request, it is not appropriate to be redirected to the login page, so a 403 error will be returned instead if your access token has expired. Access tokens may expire after a short time, e.g. 5 minutes. Refresh tokens last longer, e.g. 12 hours, and are used to get new access tokens.
The PHP app is the “client” in OAuth2, and there is no separate “resource server” in this case. The resource server is merely the protected portion of the PHP app website. PHP stores a single cookie in the web browser, which is the key to a dictionary of “session variables” stored on the webserver. The tokens are stored in the PHP session that the web browser has with the client website, and are not accessible by javascript. There was some discussion among presentation attendees regarding whether this is adequately secure, and whether or not it is necessary for the browser to have a cookie from the authorization server as well as the client website.