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
48
PHP, Meet AI
ericmann
0
48
Asynchronous Awesome
ericmann
0
140
WordPress, Meet AI
ericmann
0
35
Cooking with Credentials
ericmann
0
51
OWASP Top Ten in Review
ericmann
0
37
Monkeys in the Machine
ericmann
0
190
Asynchronous Awesome
ericmann
0
300
Evolution of PHP Security
ericmann
0
350
Other Decks in Technology
See All in Technology
ルートユーザーの活用と管理を徹底的に深掘る
yuobayashi
6
700
20250326_管理ツールの権限管理で改善したこと
sasata299
1
320
バックエンドエンジニアによるフロントエンドテスト拡充の具体的手法
kinosuke01
1
630
LINE Notify互換のボットを作った話
kenichirokimura
0
170
SSH公開鍵認証による接続 / Connecting with SSH Public Key Authentication
kaityo256
PRO
2
210
LINE API Deep Dive Q1 2025: Unlocking New Possibilities
linedevth
1
160
Why Go?
xpmatteo
0
130
AWS CDK コントリビュート はじめの一歩
yendoooo
1
120
Reactを段階的に覗いてみる
ytaisei
2
940
PHPでアクターモデルを活用したSagaパターンの実践法 / php-saga-pattern-with-actor-model
ytake
0
1k
AI・LLM事業部のSREとタスクの自動運転
shinyorke
PRO
0
300
AWS のポリシー言語 Cedar を活用した高速かつスケーラブルな認可技術の探求 #phperkaigi / PHPerKaigi 2025
ytaka23
7
1.5k
Featured
See All Featured
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.4k
Building Applications with DynamoDB
mza
94
6.3k
Embracing the Ebb and Flow
colly
85
4.6k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.5k
Why Our Code Smells
bkeepers
PRO
336
57k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.2k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
12k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.5k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.4k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
51
2.4k
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