Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Going Password-Free
Search
Eric Mann
February 03, 2017
Technology
0
150
Going Password-Free
Passwordless authentication via Tozny as presented at SunshinePHP 2017
Eric Mann
February 03, 2017
Tweet
Share
More Decks by Eric Mann
See All by Eric Mann
Evolution of PHP Security
ericmann
0
56
PHP, Meet AI
ericmann
0
56
Asynchronous Awesome
ericmann
0
150
WordPress, Meet AI
ericmann
0
39
Cooking with Credentials
ericmann
0
51
OWASP Top Ten in Review
ericmann
0
39
Monkeys in the Machine
ericmann
0
190
Asynchronous Awesome
ericmann
0
310
Evolution of PHP Security
ericmann
0
360
Other Decks in Technology
See All in Technology
勝手に!深堀り!Cloud Run worker pools / Deep dive Cloud Run worker pools
iselegant
4
600
より良い開発者体験を実現するために~開発初心者が感じた生成AIの可能性~
masakiokuda
0
230
Aspire をカスタマイズしよう & Aspire 9.2
nenonaninu
0
350
持続可能なドキュメント運用のリアル: 1年間の成果とこれから
akitok_
1
260
Dynamic Reteaming And Self Organization
miholovesq
3
700
Cross Data Platforms Meetup LT 20250422
tarotaro0129
1
890
OpenLane-V2ベンチマークと代表的な手法
kzykmyzw
0
140
企業が押さえるべきMCPの未来
takaakikakei
0
240
ビジネスとデザインとエンジニアリングを繋ぐために 一人のエンジニアは何ができるか / What can a single engineer do to connect business, design, and engineering?
kaminashi
2
860
地味にいろいろあった! 2025春のAmazon Bedrockアップデートおさらい
minorun365
PRO
2
540
Perl歴約10年のエンジニアがフルスタックTypeScriptに出会ってみた
papix
1
250
Simplify! 10 ways to reduce complexity in software development
ufried
1
160
Featured
See All Featured
Statistics for Hackers
jakevdp
798
220k
The Cost Of JavaScript in 2023
addyosmani
49
7.8k
GraphQLとの向き合い方2022年版
quramy
46
14k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
The Pragmatic Product Professional
lauravandoore
33
6.6k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.3k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.3k
Adopting Sorbet at Scale
ufuk
76
9.3k
How STYLIGHT went responsive
nonsquared
100
5.5k
Embracing the Ebb and Flow
colly
85
4.7k
A Tale of Four Properties
chriscoyier
158
23k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.7k
Transcript
Going Password-Free Sunshine PHP 2017
90
19
hunter2
None
How can we fix it? Password managers help Password strength
meters (zxcvbn) help Two-factor authentication helps But why require a password at all?
None
A PHP Example Defer to a 3rd party for email
& validation Use the SlimPHP framework for quick bootstrapping Allow either password or password-less authentication
Authentication Provider Free developer preview Powers both link-based and push-based
auth Supports PHP (and other langs)
Endpoints $app->get('/', function($request, $response, $args) { // Render index view
return $this->renderer->render($response, 'index.phtml', $args); }); $app->get('/register', function($request, $response, $args) { // Render registration view return $this->renderer->render($response, ‘register.phtml', $args); }); $app->get('/authenticated', function($request, $response, $args) { // Render protected view return $this->renderer->render($response, ‘authenticated.phtml', $args); });
Endpoints $app->get('/authenticated', function($request, $response, $args) { if ( !
isset( $_SESSION['username'] ) || ! $this->users->get( $_SESSION['username'] ) ) { return $response->withRedirect('/?error=notloggedin'); } // Render protected view return $this->renderer->render($response, ‘authenticated.phtml', $args); });
Endpoints $app->any('/login', function($request, $response, $args) { return $response->withRedirect('/?error=invalidlogin'); }); $app->get('/logout',
function($request, $response, $args) { session_destroy(); return $response->withRedirect('/?loggedout'); });
None
Middleware class PasswordAuth { private $c; public function __construct($cont)
{$this->c = $cont;} public function __invoke($req, $res, $next) { $user = $req->getParam(‘username’); $pass = $req->getParam(‘password’); if (empty($u) || empty($p)) return $res = $next($req, res); if ($this->c->validAuth($user, $pass)) { $_SESSION[‘username’] = $user; return $res = $res->withRedirect(‘/authenticated’); } return $res = $res->withRedirect(‘/?error=invalidlogin’); } }
Endpoints $app->any('/login', function($request, $response, $args) { return $response->withRedirect('/?error=invalidlogin'); })->add(new PasswordAuth($container));
Endpoints $app->any('/login', function($request, $response, $args) { if($request->getParam(‘magiclink’) && $request->getParam(‘username’)) {
$user = $this->users->get($request->getParam(‘username’)); $sent = sendMagicLink($user->email); if(‘ok’ === $sent[‘return’]) return $response->withRedirect(‘/?message=checkemail’); } return $response->withRedirect('/?error=invalidlogin'); })->add(new PasswordAuth($container));
Middleware class MagicLinkAuth { private $c; public function __construct($cont)
{$this->c = $cont;} public function __invoke($req, $res, $next) { $toznyo = $req->getParam(‘toznyo’); $toznyr = $req->getParam(‘toznyr’); if (empty($toznyo) || empty($toznyr)) { $res = $next($req, res); } else { if ($this->c->validLink($toznyo, $toznyr) { $user = $this->c->users->getUserFromLink($toznyo); $_SESSION[‘username’] = $user->username; $res = $res->withRedirect(‘/authenticated’); } } return $res; } }
Endpoints $app->any('/login', function($request, $response, $args) { return $response->withRedirect('/?error=invalidlogin'); })->add(new PasswordAuth($container))->add(new
MagicLinkAuth($container));
What just happened? Registered users can authenticate with their password
Registered users can request a secure, one-time login link sent to their inbox The application doesn’t care which way the users authenticate
How does this benefit us? One less password for users
to remember More flexible authentication schemes for existing users The middleware stack could be further extended to support TOTP/HOTP/ U2F/etc
What are the risks? Your users’ accounts are only as
secure as their email
Questions?
Thank You! Eric Mann - @ericmann - http://eam.me/10v - https://tozny.com