Skip to content

Commit 97fd151

Browse files
committed
Added registration example code to README
1 parent cdd0a04 commit 97fd151

2 files changed

Lines changed: 138 additions & 5 deletions

File tree

README.md

Lines changed: 134 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ FIDO's U2F enables you to add a simple unobtrusive method of 2nd factor authenti
1717
1. [Registration Process Flow](#registration-process-flow)
1818
1. [Authentication Process Flow](#authentication-process-flow)
1919
6. [Example Code](#example-code)
20+
1. [Compatibility Check](#compatibility-code)
2021
1. [Registration Code](#registration-code)
2122
1. [Authentication Code](#authentication-code)
2223
7. [Frameworks](#frameworks)
@@ -37,11 +38,11 @@ A few **things you need** to know before working with this:
3738
1. [**_OpenSSL_**](#openssl)
3839
2. [**_A Datastore_**](#recommended-datastore-structure) You need some kind of datastore for all your U2F registered users (although if you have a system with user authentication I'm presuming you've got this one sorted).
3940
3. [**_Client-side Handling_**](#client-side) You need to be able to communicate with a some kind of device.
40-
4. [**_A HTTPS URL_**](#https-and-ssl) This is very important, without HTTPS Chrome will refuse to communicate with you.
41+
4. [**_A HTTPS URL_**](#https-and-ssl) This is very important, without HTTPS U2F simply will not work.
4142

4243
### OpenSSL
4344

44-
... Info about installing OpenSSL ...
45+
This repository requires OpenSSL 1.0.0 or higher. For further details on installing OpenSSL please refer to the php manual http://php.net/manual/en/openssl.installation.php .
4546

4647
### Client-side (The magic JavaScript Bit of talking with a USB device)
4748

@@ -52,7 +53,7 @@ My presumption is that if you are looking to add U2F authentication to a php sys
5253

5354
### HTTPS and SSL
5455

55-
Without a HTTPS URL your code won't work, so get one for your localhost, get one for your production. https://letsencrypt.org/
56+
For U2F to work your website/service must use a HTTPS URL. Without a HTTPS URL your code won't work, so get one for your localhost, get one for your production. https://letsencrypt.org/
5657

5758

5859
## Terminology
@@ -80,6 +81,7 @@ TODO the descriptions
8081
### Registration Process Flow
8182

8283
1. User navigates to a 2nd factor authentication page in your application.
84+
... TODO add the rest of the registration process flow ...
8385

8486
### Authentication Process Flow
8587

@@ -107,16 +109,144 @@ You can also install it with the following:
107109

108110
`composer require samyoul/u2f-php-server-examples`
109111

112+
### Compatibility Code
113+
114+
You'll only ever need to use this method call once per installation and only in the context of debugging if the class is giving you unexpected errors. This method call wil check your OpenSSL version and ensure it is at least 1.0.0 .
115+
116+
```php
117+
<?php
118+
119+
require('vendor/autoload.php');
120+
use Samyoul\U2F;
121+
122+
var_dump(U2F::checkOpenSSLVersion());
123+
```
124+
110125
### Registration Code
111126

127+
**Starting the registration process:**
128+
129+
We assume that user has successfully authenticated and wishes to register.
130+
131+
```php
132+
<?php
133+
134+
require('vendor/autoload.php');
135+
use Samyoul\U2F;
136+
137+
session_start();
138+
139+
// This can be anything, but usually easier if you choose your applications domain and top level domain.
140+
$appId = "yourdomain.tld";
141+
142+
// Call the makeRegistration method, passing in the app ID
143+
$registrationData = U2F::makeRegistration($appId);
144+
145+
// Store the request for later
146+
$_SESSION['registrationRequest'] = $registrationData['request'];
147+
148+
// Extract the request and signatures, JSON encode them so we can give the data to our javaScript magic
149+
$jsRequest = json_encode($registrationData['request']);
150+
$jsSignatures = json_encode($registrationData['signatures']);
151+
152+
// now pass the data to a fictitious view.
153+
echo View::make('template/location/u2f-registration.html', compact("jsRequest", "jsSignatures"));
154+
```
155+
156+
**Client-side, Talking To The USB**
157+
158+
Non-AJAX client-side registration of U2F key token. AJAX can of course be used in your application, but it is easier to demonstrate a linear process without AJAX and callbacks.
159+
160+
```
161+
<html>
162+
<head>
163+
<title>U2F Key Registration</title>
164+
</head>
165+
<body>
166+
<h1>U2F Registration</h1>
167+
<h2>Please enter your FIDO U2F device into your computer's USB port. Then confirm registration on the device.</h2>
168+
169+
<div style="display:none;">
170+
<form id="u2f_submission" method="post" action="auth/u2f-registration/confirm">
171+
<input id="u2f_registration_response" name="registration_response" value="" />
172+
</form>
173+
</div>
174+
175+
<script type="javascript" src="https://raw.githubusercontent.com/google/u2f-ref-code/master/u2f-gae-demo/war/js/u2f-api.js"></script>
176+
<script>
177+
setTimeout(function() {
178+
179+
// A magic JS function that talks to the USB device. This function will keep polling for the USB device until it finds one.
180+
u2f.register([<?php echo $jsRequest ?>], <?php echo $jsSignatures ?>], function(data) {
181+
182+
// Handle returning error data
183+
if(data.errorCode && errorCode != 0) {
184+
alert("registration failed with error: " + data.errorCode);
185+
// Or handle the error however you'd like.
186+
187+
return;
188+
}
189+
190+
// On success process the data from USB device to send to the server
191+
var registration_response = JSON.stringify(data);
192+
193+
// Get the form items so we can send data back to the server
194+
var form = document.getElementById('u2f_submission');
195+
var response = document.getElementById('u2f_registration_response');
196+
197+
// Fill and submit form.
198+
response.value = JSON.stringify(registration_response);
199+
form.submit();
200+
});
201+
}, 1000);
202+
</script>
203+
</body>
204+
</html>
205+
```
206+
207+
**Validation and Key Storage**
208+
209+
This is the last stage of registration. Validate the registration response data against the original request data.
210+
112211
```php
113212
<?php
114-
// All the amazing registration code
115213

214+
require('vendor/autoload.php');
215+
use Samyoul\U2F;
216+
217+
session_start();
218+
219+
// Fictitious function representing getting the authenticated user object
220+
$user = getAuthenticatedUser();
221+
222+
try {
223+
224+
// Validate the registration response against the registration request.
225+
// The output are the credentials you need to store for U2F authentication.
226+
$validatedRegistration = U2F::register(
227+
$_SESSION['registrationRequest'],
228+
json_decode($_POST['u2f_registration_response'])
229+
);
230+
231+
// Fictitious function representing the storing of the validated U2F registration data against the authenticated user.
232+
$user->storeRegistration($validatedRegistration);
233+
234+
// Then let your user know what happened
235+
$userMessage = "Success";
236+
} catch( Exception $e ) {
237+
$userMessage = "We had an error: ". $e->getMessage();
238+
}
239+
240+
//Fictitious view.
241+
echo View::make('template/location/u2f-registration-result.html', ['userMessage' => $userMessage]);
116242
```
117243

118244
### Authentication Code
119245

246+
**Starting the authentication process:**
247+
248+
We assume that user has successfully authenticated and has previously registered.
249+
120250
```php
121251
<?php
122252
// All the amazing authentication code

src/U2F.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ public static function makeRegistration($appId, array $registrations = array())
5555
{
5656
$request = new RegistrationRequest(static::createChallenge(), $appId);
5757
$signatures = static::makeAuthentication($registrations, $appId);
58-
return [$request, $signatures];
58+
return [
59+
"request" => $request,
60+
"signatures" => $signatures
61+
];
5962
}
6063

6164
/**

0 commit comments

Comments
 (0)