Jump to content

Recommended Posts

Posted

Good day!

I am looking for a solution to do a login-with-a link functionality. A site should generate and send via email a link to a user. That link should contain (as I can imagine) a login and some kind of token. Following that link a user is able to get automatically authenticated on a site and view the page, otherwise inaccessible.

 

Posted (edited)

Just been there, thanks. I am hoping to find something on-site (or at least with an integration as a module) :-[ .

P.S. And I think this link has all the rights to be here, Sergio.

Edited by Ivan Gretsky
  • Like 1
Posted

The whole process is not that difficult. Create a long random string and store in in the db. When a link is hit, check the db for that token and if found (and still valid?) login the user and delete the token from the db. The only real pain point could be the "create a random string" part depending on how secure the whole thing should be.

  • Like 3
Posted

Yes, that is the route I will probably take. I think about storing the token in the user template and use it only in pair with login. I am planning to use forceLogin to authenticate without password on condition if the token in the url matches the token stored in the user template.

Posted

@Ivan Gretsky, there is a crypto module here that can create random token strings for you.

If I remember correctly, you can just do this;

$num_chars  = 32; // The length of the token you want. Adjust as needed 
$random_key = CryptoPPP::genKeys(1);  // Generates a seed key
$token      = CryptoPPP::keyToToken($random_key, $num_chars); // Convert to string token

You can also define the character set that the random string is to use if you aren't happy with the default one. In fact, if you are going to use the token in a returned link, you'll definitely want to change the default character set used in the generation to only use url-safe characters.

  • Like 6
  • 5 months later...
  • 10 months later...
Posted
29 minutes ago, szabesz said:

@Ivan Gretsky

Hi Ivan,
Did you implement it? I will probably need it too, so if you could boost my thinking with an example code snippet that would be appreciated.

Ah, never mind Ivan! Things change quickly, we decided to use email+password instead :) Cheers!

Posted

Morning,
To tell the truth I'm still interested :) If I can also do it quickly it makes sense to convince the client. So if you have the time, please share it. Thanks in advance!

Posted

Ok.

1. We need to generate a unique token for a user and store it. The simple way to do that is to add a field to user page (login_token in the example). To make process easier we make a method for that via hook:

// site/init.php

$wire->addHook("User()::getToken", function(HookEvent $event) {
	$page = $event->object;
	if (empty($page->login_token)) {
		$page->of(false);
		$page->login_token = generateToken(12);
		$page->save();
		$page->of(true);
	}
	return $event->return = $page->login_token;
});

The genereateToken() function is yours to implement as you wish.

2. Now we can generate a link:

$link = $page->httpUrl . "?user=". $user->id . "&token=". $user->getToken();

3. Finally we need to handle those parameters and make user autologin:

// site/templates/_init.php

if ($userToLoginId = $sanitizer->int($input->get->user)) {
	
	$url = $page->url;
	$userToLogin = $users->get($userToLoginId);
	$tokenToLoginWith = $sanitizer->text($input->get->token);
	
	if ($userToLogin->id && $tokenToLoginWith && strcmp($userToLogin->login_token, $tokenToLoginWith) == 0) {
		$loggedInUser = $session->forceLogin($userToLogin);
		if ($loggedInUser) {
			$user = $loggedInUser;
		};
		$session->redirect($url);
	}
}

We can then nullify user token if we want it to be only a one-time ticket.

I rewrote whole lot of stuff, so might not work  straight away, but surely you can fix it @szabesz)) Hope I am not missing something essential.

  • Like 4
  • Thanks 1
Posted

Thank you Ivan, I do appreciate it. I will have time on the weekend to implement my version. I might even turn it into a module, who knows? (I certainly don't :D ). 

  • Like 2

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...