Ivan Gretsky Posted July 5, 2016 Posted July 5, 2016 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.
Sergio Posted July 5, 2016 Posted July 5, 2016 Take a look at auth0.com: https://auth0.com/docs/connections/passwordless/spa-email-link 1
Ivan Gretsky Posted July 5, 2016 Author Posted July 5, 2016 (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 July 5, 2016 by Ivan Gretsky 1
LostKobrakai Posted July 5, 2016 Posted July 5, 2016 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. 3
Ivan Gretsky Posted July 5, 2016 Author Posted July 5, 2016 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.
netcarver Posted July 5, 2016 Posted July 5, 2016 @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. 6
Ivan Gretsky Posted December 28, 2016 Author Posted December 28, 2016 Just to have a reference. There is a native PW way to generate random string. Do not know how it compares to other ways, but it is here to use. 2
szabesz Posted November 9, 2017 Posted November 9, 2017 @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.
szabesz Posted November 9, 2017 Posted November 9, 2017 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!
Ivan Gretsky Posted November 10, 2017 Author Posted November 10, 2017 Hey, @szabesz! It was done. Actually It was pretty easy (at least the way we implemented it without much security overthinking). Would be happy to share code if needed. But it is essentually what @LostKobrakai wrote. 1 1
szabesz Posted November 10, 2017 Posted November 10, 2017 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!
Ivan Gretsky Posted November 10, 2017 Author Posted November 10, 2017 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. 4 1
szabesz Posted November 10, 2017 Posted November 10, 2017 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 ). 2
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now