简体   繁体   中英

Login on webapp by token sent by e-mail

I am building a webapp that is supposed to be hosted in my company servers and used through the intranet. The requirements are:

  1. The user accesses the webapp.
  2. The app requests an e-mail address.
  3. An e-mail containing a unique link (token) is sent to the address.
  4. The user clicks on the link to log in without a password.

I am developing the webapp using Symfony3 and I thought of using the FriendsOfSymfony User bundle. How can I acheive that? FOSUserBundle is not mandatory.

The login functionalities you want to achieve do not diver that much from eg resetting a password by email. Except the temporary token in your use case is used to authenticate the user instead of authenticating a password reset.

A very simple explanation

You should create an entity that stores the authentication token, eg AutoLogin that has user , token and a timestamp property.

On the submit of your 'authentication form' a new AutoLogin record gets stored with a relationship towards the user and the user gets notified by email.

Whenever the user clicks the link you should have a method that validates the timestamp for a timeframe and authenticate the user by your user provider.

Examples

Symfony 2: AutoLogin

I think after you accepted the email this is what you can do:

sent url to email like this

<?php
$url = "http://example.com/login.php?token=$token";
?>

Then you login page

<?php
// retrieve token
if (isset($_GET["token"]) && preg_match('/^[0-9A-F]{40}$/i', $_GET["token"]))
{
$token = $_GET["token"];
}
else {
throw new Exception("Valid token not provided.");
}
// verify token
$query = $db->prepare("SELECT username, tstamp FROM pending_users WHERE token = ?");
$query->execute(array($token));
$row = $query->fetch(PDO::FETCH_ASSOC);
$query->closeCursor();

if ($row) {
    extract($row);
}
else {
    throw new Exception("Valid token not provided.");
}

// do action here, like activating a user account/redirect
// ...

// delete token so it can't be used again
$query = $db->prepare(
    "DELETE FROM pending_users WHERE username = ? AND token = ? AND tstamp = ?",
);
$query->execute(
    array(
        $username,
        $token,
        $tstamp
    )
);

Assuming you have tables like the ones in my queries. Hope i answered you well

There is a service called fos_user.security.login_manager that can help:

public function loginByTokenAction($token)
{
  $em = $this->getDoctrine()->getManager();
  $user = $em->getRepository('AppBundle:User')->findOneByToken($token);
  $this->container->get('fos_user.security.login_manager')->loginUser('firewall_name', $user);
  // ...
}

source : https://github.com/symfony/symfony/pull/13062

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM