secure your app - · pdf filesecure your app with 2fa ... if the user's code matches,...
TRANSCRIPT
![Page 1: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/1.jpg)
Secure your appwith 2FA
Rob Allen ~ @akrabat ~ November 2015
![Page 2: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/2.jpg)
Your users' passwords willbe leaked
(It might not even be your fault)
![Page 3: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/3.jpg)
Passwords have leaked from
Sony Zappos JP Morgan GapFacebook Twitter eBay AT&TAdobe Target Blizzard TalkTalkEvernote Yahoo! Steam UbisoftKickstarter Home Depot TK Maxx VodafoneHP AOL Citigroup WorldPayGmail last.fm Apple SnapChatUbuntu D&B Formspring Betfair
![Page 4: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/4.jpg)
It will take 14 minutes* to crackone of your users' passwords
(English word, stored using bcrypt)
![Page 5: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/5.jpg)
Two-factor authenticationprotects your users
![Page 6: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/6.jpg)
What is 2FA?
![Page 7: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/7.jpg)
Implementation on a website
![Page 8: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/8.jpg)
Implementation on a website
![Page 9: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/9.jpg)
How do we send the code?
![Page 10: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/10.jpg)
Email• Used by Steam• Wide adoption (everyone has an email address!)• Likely failures: delivery problems, blocking, spam etc• Usually slow!• Same system as recover password…
![Page 11: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/11.jpg)
SMS• Used by Twitter & LinkedIn• Wide adoption• But, SMS can be delayed & could cost to receive
![Page 12: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/12.jpg)
Physical device• Used by banks, YubiKey, Blizzard, etc• Small, long battery life• But, expensive
![Page 13: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/13.jpg)
App• Easy to use• No Internet or cellular connection required• App is free and trusted
![Page 14: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/14.jpg)
One Time Password algorithms
![Page 15: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/15.jpg)
HOTP• HMAC-based One-Time Password algorithm• Computed from shared secret and counter• New code each time you press the button• RFC 4226
![Page 16: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/16.jpg)
HOTP algorithm: step 1
![Page 17: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/17.jpg)
HOTP algorithm: step 2
![Page 18: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/18.jpg)
HOTP algorithm: step 3
![Page 19: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/19.jpg)
HOTP in PHP 1 function hotp($secret, $counter)
2 {
3 $bin_counter = pack('J*', $counter);
4 $hash = hash_hmac('sha1', $bin_counter, $secret, true);
5
6 $offset = ord($hash[19]) & 0xf;
7
8 $bin_code =
9 ((ord($hash[$offset+0]) & 0x7f) << 24 ) |
10 ((ord($hash[$offset+1]) & 0xff) << 16 ) |
11 ((ord($hash[$offset+2]) & 0xff) << 8 ) |
12 (ord($hash[$offset+3]) & 0xff);
13
14 return $bin_code % pow(10, 6);
15 }
![Page 20: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/20.jpg)
Validation process
If the user's code matches, then increment counter by 1If the user's code does not match, then look-ahead a little
Resync if can’t find in look-ahead:
1. Ask the user for two consecutive codes2. Look ahead further from last known counter until the 2 codes are
found3. Limit look-ahead to minimise attack area. e.g. 400
![Page 21: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/21.jpg)
TOTP• Time-based One-Time Password algorithm• Computed from shared secret and current time• Increases in 30 second intervals• RFC 6238
![Page 22: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/22.jpg)
TOTP Algorithm
![Page 23: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/23.jpg)
TOTP in PHP1 function totp($secret)
2 {
3 $counter = floor(time() / 30);
4
5 return hotp($secret, $counter);
6 }
![Page 24: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/24.jpg)
Implementing 2FAin your application
![Page 25: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/25.jpg)
Use a library!$composer require sonata-project/google-authenticator
Usage:
$g = new \Google\Authenticator\GoogleAuthenticator();
// create new secret and QR code
$secret = $g->generateSecret();
$qrCode = $g->getURL('rob', 'akrabat.com', $secret);
// validation of code
$g->checkCode($secret, $_POST['code']);
![Page 26: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/26.jpg)
Things to do
1. Registration of Authenticator2. Check 2FA TOTP code during login
![Page 27: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/27.jpg)
Set up 2FA
![Page 28: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/28.jpg)
Set up 2FA
![Page 29: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/29.jpg)
Set up 2FA
![Page 30: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/30.jpg)
Set up 2FA
![Page 31: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/31.jpg)
Set up 2FA
![Page 32: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/32.jpg)
Set up 2FA: code 1 $app->get('/setup2fa', function () use ($app) {
2 $user = $_SESSION['user'];
3
4 $g = new \Google\Authenticator\GoogleAuthenticator();
5 $secret = $g->generateSecret();
6 $qrCodeUrl = $g->getURL($user->getUsername(),
7 '2fa.dev', $secret);
8
9 $app->flash('secret', $secret);
10 $app->render('setup2fa.twig', [
11 'user' => $_SESSION['user'],
12 'secret' => $secret,
13 'qrCodeUrl' => $qrCodeUrl,
14 ]);
15 });
![Page 33: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/33.jpg)
Set up 2FA: template 1 <h1>Set up 2FA</h1>
2
3 <p>Scan this code into Google Authenticator:</p>
4 <img src="{{ qrCodeUrl }}">
5 <p>or enter this code: <tt>{{ secret }}</tt></p>
6
7 <p>Enter code from Google Authenticator to confirm:</p>
8 <form method="POST" action="/setup2fa">
9 <div class="form-group">
10 <input name="code" maxlength="6">
11 <button type="submit">Confirm</button>
12 </div>
13 </form>
![Page 34: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/34.jpg)
Set up 2FA: submission 1 $app->post('/setup2fa', function () use ($app) {
2 $secret = $app->environment['slim.flash']['secret'];
3 $code = $app->request->post('code');
4 $g = new \Google\Authenticator\GoogleAuthenticator();
5 if ($g->checkCode($secret, $code)) {
6 // code is valid - store into user record
7 $user = $_SESSION['user'];
8 $user->setSecret($secret);
9 $mapper = $app->userMapper;
10 $mapper->save($user);
11 $app->flash('message', 'Successfully set up 2FA');
12 $app->redirect('/');
13 }
14 $app->flash('error', 'Failed to confirm code');
15 $app->redirect('/setup2fa');
16 });
![Page 35: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/35.jpg)
Set up of 2FA
![Page 36: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/36.jpg)
Logging in
![Page 37: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/37.jpg)
Logging in
![Page 38: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/38.jpg)
Logging in
![Page 39: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/39.jpg)
Logging in
![Page 40: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/40.jpg)
Logging in
![Page 41: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/41.jpg)
Login: display username/pwd1 $app->get('/login', function () use ($app) {
2 $app->render('login.twig');
3 });
![Page 42: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/42.jpg)
Login: display username/pwd 1 <h1>Login</h1>
2
3 <form method="POST" action="/login" class="form-horizontal">
4 <div class="form-group">
5 <label for="username">Username</label>
6 <div><input type="text" id="username" name="username"></div>
7 </div>
8 <div class="form-group">
9 <label for="password">Password</label>
10 <div><input type="password" id="p :)
11 assword" name="password"></div>
12 </div>
13 <div class="form-group">
14 <button type="submit">Log in</button>
15 </div>
16 </form>
![Page 43: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/43.jpg)
Login: process username/pwd 1 $app->post('/login', function () use ($app, $mapper) {
2 $username = $app->request->post('username');
3 $password = $app->request->post('password');
4 $user = $mapper->load($username);
5 $valid = password_verify($password, $user->getPassword());
6 if ($valid) {
7 if ($user->getSecret()) {
8 $_SESSION['user_in_progress'] = $user;
9 $app->redirect('/auth2fa');
10 }
11 $_SESSION['user'] = $user;
12 $app->redirect('/');
13 }
14 $app->flash('error', 'Failed to log in');
15 $app->redirect('/login');
16 });
![Page 44: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/44.jpg)
Login: 2FA code form1 $app->get('/auth2fa', function () use ($app) {
2 $app->render('auth2fa.twig');
3 });
auth2fa.twig:
1 <h1>2FA authentication</h1>
2
3 <p>Enter the code from Google Authenticator
4 to complete login:</p>
5 <form method="POST" action="/auth2fa">
6 <div class="form-group">
7 <input name="code" maxlength="6">
8 <button type="submit">Submit</button>
9 </div>
10 </form>
![Page 45: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/45.jpg)
Login: process 2FA code 1 $app->post('/auth2fa', function () use ($app) {
2 $user = $_SESSION['user_in_progress'];
3 $secret = $user->getSecret();
4 $code = $app->request->post('code');
5
6 $g = new \Google\Authenticator\GoogleAuthenticator();
7 if ($g->checkCode($secret, $code)) {
8 // code is valid!
9 $_SESSION['user'] = $_SESSION['user_in_progress'];
10 unset($_SESSION['user_in_progress']);
11 $app->flash('message', 'Successfully logged in');
12 $app->redirect('/');
13 }
14
15 $app->flash('error', 'Failed to confirm code');
16 $app->redirect('/auth2fa');
17 });
![Page 46: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/46.jpg)
Login
![Page 47: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/47.jpg)
2FA code
![Page 48: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/48.jpg)
Round out solution• Prevent brute force attacks• Consider adding a “remember this browser” feature• Need a solution for a lost/new phone
Example project: https://github.com/akrabat/slim-2fa
![Page 49: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/49.jpg)
Hardware OTP: YubiKey
![Page 50: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/50.jpg)
Operation
1. Insert YubiKey into USB slot2. Select input field on form3. Press button to fill in OTP field4. Server validates OTP with YubiCloud service
![Page 51: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/51.jpg)
Yubikey’s OTP
![Page 52: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/52.jpg)
Coding it$composer require enygma/yubikey
Usage:
$v = new \Yubikey\Validate($apiKey, $clientId);
$response = $v->check($_POST['yubikey_code']);
if ($response->success() === true) {
// allow into website
}
![Page 53: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/53.jpg)
Login: process yubikey code 1 $app->post('/auth2fa', function () use ($app) {
2 $apiKey = $app->settings['yubikey']['api_key'];
3 $clientId = $app->settings['yubikey']['client_id'];
4
5 $v = new \Yubikey\Validate($apiKey, $clientId);
6 $response = $v->check($app->request->post('code'));
7
8 if ($response->success() === true) {
9 // Successfully logged in
10 $_SESSION['user'] = $_SESSION['user_in_progress'];
11 unset($_SESSION['user_in_progress']);
12 $app->redirect('/');
13 }
14 $app->flash('error', 'Failed to confirm code');
15 $app->redirect('/auth2fa');
16 });
![Page 54: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/54.jpg)
That’s all there is to it!
![Page 55: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/55.jpg)
Pre-built plugins
![Page 56: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/56.jpg)
Pre-built pluginsDrupal:
• Two-factor Authentication• Yubikey
WordPress:
• Two-Factor• (many others!)
Joomla:
• Built-in!
![Page 57: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/57.jpg)
Drupal
![Page 58: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/58.jpg)
Set up
![Page 59: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/59.jpg)
Set up
![Page 60: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/60.jpg)
Log in
![Page 61: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/61.jpg)
WordPress
![Page 62: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/62.jpg)
Set up
![Page 63: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/63.jpg)
Log in
![Page 64: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/64.jpg)
Log in
![Page 65: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/65.jpg)
Joomla
![Page 66: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/66.jpg)
Log in
![Page 67: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/67.jpg)
That secret key field
![Page 68: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/68.jpg)
To sum up
![Page 69: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/69.jpg)
To sum up
Two-factor authentication isn’t hard!
![Page 70: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/70.jpg)
Questions?
https://joind.in/14761
Rob Allen - http://akrabat.com - @akrabat
![Page 71: Secure your app - · PDF fileSecure your app with 2FA ... If the user's code matches, then increment counter by 1 ... 8](https://reader031.vdocument.in/reader031/viewer/2022030502/5aae99e87f8b9aa8438c481f/html5/thumbnails/71.jpg)
Thank you!
https://joind.in/14761
Rob Allen - http://akrabat.com - @akrabat