Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Going Password-Free

Eric Mann
February 03, 2017

Going Password-Free

Passwordless authentication via Tozny as presented at SunshinePHP 2017

Eric Mann

February 03, 2017
Tweet

More Decks by Eric Mann

Other Decks in Technology

Transcript

  1. 90

  2. 19

  3. How can we fix it? Password managers help Password strength

    meters (zxcvbn) help Two-factor authentication helps But why require a password at all?
  4. 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
  5. 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);
 });
  6. 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);
 });
  7. 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');
 });
  8. 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’);
 }
 }
  9. 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));
  10. 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;
 }
 }
  11. 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
  12. 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