-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.php
196 lines (183 loc) · 6.61 KB
/
index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
<?php
require_once __DIR__ . '/vendor/autoload.php';
use eustasy\Authenticatron;
include __DIR__ . '/assets/header.php';
$accountName = 'John Smith';
$issuer = 'Authenticatron Example Page';
if (!empty($_POST['secondfactor_secret'])) {
$secret = $_POST['secondfactor_secret'];
} elseif (!empty($_GET['secret'])) {
$secret = $_GET['secret'];
}
?>
<div class="break clear"></div>
<div class="right fake-left">
<h1>Installation</h1>
</div>
<div class="clear"></div>
<div class="left">
<p>Install</p>
</div>
<div class="right">
<p><code>composer require eustasy/authenticatron</code></p>
</div>
<div class="clear"></div>
<div class="left">
<p>Require</p>
</div>
<div class="right">
<pre>//// Import eustasy\Authenticatron with Composer
require_once __DIR__ . '/vendor/autoload.php';
use eustasy\Authenticatron;</pre>
</div>
<div class="break clear"></div>
<div class="right fake-left">
<h1>Quick Implementation</h1>
</div>
<div class="clear"></div>
<div class="half half-left">
<div class="right fake-left">
<h2>Step 1.</h2>
<p class="subtitle"><code>Authenticatron::new</code> to create a new secret for a member, and fetch a secure image for scanning.</p>
</div>
<div class="break clear"></div>
<div class="left">
<p>Code</p>
</div>
<div class="right">
<p><code>Authenticatron::new($accountName, $issuer)</code></p>
</div>
<div class="break clear"></div>
<div class="left">
<p>Input</p>
</div>
<div class="right">
<p><code>$accountName</code> is a string containing your members username or nice-name, perferably something unique and quickly identifiable.</p>
<p><code>$issuer</code> is a string containing the name of your app or site.</p>
</div>
<div class="break clear"></div>
<div class="left">
<p>Output</p>
</div>
<div class="right">
<p>Outputs an array, where <code>Secret</code> is the Secret for the member, <code>URL</code> is an OTPAuth URL, and <code>QR</code> is the Data64 URI for the QR code.</p>
<pre><?php
if (!empty($secret)) {
$secondAuth['Secret'] = $secret;
$secondAuth['URL'] = Authenticatron::getUrl($accountName, $secret, $issuer);
$secondAuth['QR'] = Authenticatron::generateQrCode($secondAuth['URL']);
} else {
$secondAuth = Authenticatron::new($accountName, $issuer);
$secret = $secondAuth['Secret'];
}
var_dump($secondAuth);
?></pre>
</div>
<div class="break clear"></div>
<div class="left">
<p>Handling</p>
</div>
<div class="right">
<p>You'll want to store <code>['Secret']</code> with the member, but make sure you get them to confirm a code before enforcing it, or it might not have worked and they would be locked out of their account. Make sure that this is as protected as a password hash.</p>
<br>
<p><code>['QR']</code> is the Data64 URI for the QR code. You can simply echo it into an <code>img</code> element like this:</p>
<pre><img src="<?php echo $secondAuth['QR']; ?>" alt="Second Factor Authentication Code"></pre>
</div>
<div class="break clear"></div>
<div class="left">
<p>Example</p>
<img alt="Google Camera Icon" src="assets/google_images-128.png">
</div>
<div class="right">
<p>Try scanning this into an app like <a href="https://m.google.com/authenticator">Google Authenticator</a>. You should see a code and a countdown clock until it changes.</p>
<img alt="QR Code for 2nd factor authentication" src="<?php echo $secondAuth['QR']; ?>">
</div>
</div>
<div class="break-small clear-small"></div>
<div class="half half-right">
<div class="right fake-left">
<h2>Step 2.</h2>
<p class="subtitle">Use <code>Authenticatron::checkCode</code> to confirm the setup and check time-unique codes at every login.</p>
</div>
<div class="break clear"></div>
<div class="left">
<p>Code</p>
</div>
<div class="right">
<p><code>Authenticatron::checkCode($code, $secret)</code></p>
</div>
<div class="break clear"></div>
<div class="left">
<p>Input</p>
</div>
<div class="right">
<p><code>$code</code> is the user input, the code that is generated on their device for authentication. Should be numeric-only in most cases, alpha-numeric if you change some settings.</p>
<p><code>$secret</code> is the secret the member scanned that you securely stored for later.</p>
<p><code>$variance</code> is an optional integer indicating the adjustment of codes with a 30 second value. Defaults to 2 either side, or 1 minute.</p>
</div>
<div class="break clear"></div>
<div class="left">
<p>Output</p>
</div>
<div class="right">
<p>Outputs a boolean value, <code>true</code> if the entered code is within allowed range, <code>false</code> if not.</p>
<pre><?php
$code = Authenticatron::getCode($secret);
$check = Authenticatron::checkCode($code, $secret);
var_dump($check);
?></pre>
</div>
<div class="break clear"></div>
<div class="left">
<p>Handling</p>
</div>
<div class="right">
<p>You only need to check an input is alpha-numeric, and maybe 6 characters long before checking it against a retreieved secret.</p>
<pre>$secret = ...;
if (
strlen($_POST['secondfactor_code']) == 6 &&
ctype_alnum($_POST['secondfactor_code'])
) {
if ( Authenticatron::checkCode($_POST['secondfactor_code'], $secret) ) {
// Authenticated, log in...
} else {
// Incorrect code
}
} else {
// Invalid entry
}</pre>
</div>
<div class="break clear"></div>
<div class="left" id="example">
<p>Example</p>
<img alt="Google Authenticator Icon" src="assets/google_authenticator_v3_480s.png">
</div>
<div class="right"><?php
if (!empty($_POST['secondfactor_code'])) {
if (
strlen($_POST['secondfactor_code']) == 6 &&
ctype_alnum($_POST['secondfactor_code'])
) {
if (Authenticatron::checkCode($_POST['secondfactor_code'], $secret)) {
echo '<p class="color-flatui-nephritis">Correct Code: The code you entered was correct, congratulations!</h3>';
} else {
echo '<p class="color-flatui-pomegranate">Incorrect Code: The code you entered was not valid at this time. Codes are valid for 30 seconds.</p>';
}
} else {
echo '<p class="color-flatui-pomegranate">Invalid Entry: The code you entered was not 6 characters long, and alphanumeric.</p>';
}
echo '<div class="break clear"></div>';
}
?>
<p>Enter the code that your device generates after scanning the image to from Step 1.</p>
<form action="#example" method="POST">
<!-- WARNING: You should never reveal real secrets like this. -->
<input name="secondfactor_secret" type="hidden" value="<?php echo $secret; ?>">
<label for="secondfactor_code">2fa Code</label>
<input name="secondfactor_code" id="secondfactor_code" type="text" maxlength="6">
<input type="submit" value="Check">
</form>
</div>
</div>
<?php
include __DIR__ . '/assets/footer.php';