hberg539 Posted May 23, 2018 Share Posted May 23, 2018 Hello, how can i compare a stored password (InputfieldPassword) with a selector? E.g.: $pages->find("template=test,user=abc,password=<hash>"); How can i create that hash from the user input? Or should i just put the plain-text password here? PS: I don't want to use the processwire user module (would be overkill for my usage). Thanks. Best regards, Kevin Link to comment Share on other sites More sharing options...
flydev Posted May 23, 2018 Share Posted May 23, 2018 Link to comment Share on other sites More sharing options...
hberg539 Posted May 23, 2018 Author Share Posted May 23, 2018 Thanks flydev, but your link handles the password with the processwire user management (as far as i see it), which i don't want to use. I just have a template with a password field which i would like to compare against a plaintext user input. Link to comment Share on other sites More sharing options...
flydev Posted May 23, 2018 Share Posted May 23, 2018 with the thread I linked above, you can achieve in two lines what you want : $password = 'password1337'; // user input password $hash = $pages->get('/passwords/')->password; // password field from page "passwords" $result = $hash->matches($password); // check if password hash equal to stored password (hash) bd($result); // dump the result with TracyDebugger - return true or false easy as always.. Link to comment Share on other sites More sharing options...
hberg539 Posted May 23, 2018 Author Share Posted May 23, 2018 Thanks. It works this way, but i need to iterate over all the pages and compare each with the user input (using the ->match() method). In the good old sql way, i would do something like "select * from pages where user = 'xxx' and password = '<hashed_password>'"; In the Find-Page of the admin interface, the password-field is detected as "subfield" and i can choose between the field itself or "salt". Have a look here: It doesn't find the result, although the password is correct. I need some way to generate the "data" or the salted version of the password, but i just don't know how. Link to comment Share on other sites More sharing options...
flydev Posted May 23, 2018 Share Posted May 23, 2018 32 minutes ago, hberg539 said: It doesn't find the result, although the password is correct. So I assume you have a field called "email" in the template "firma" (correct ?). If its not the case, the Find-Page tool will not work as the user template is a system template. Anyway, to have a result here, you have to check your password with the HASH you get and not the plain text password. The tool do not convert the password to a hash on the fly, same as example $pages->find("a selector") will not work with a plain text password; And ProcessWire do not store the plain text password, so trying to compare it here do not make sense. With hash comparison : With plain text password comparison : Link to comment Share on other sites More sharing options...
hberg539 Posted May 23, 2018 Author Share Posted May 23, 2018 (edited) Yes, i don't use the user template or any user management from processwire. How do i generate the hash of the password? ? When in the admin panel, the hash generation is done by the field itself: Thank you. Edited May 23, 2018 by hberg539 Link to comment Share on other sites More sharing options...
flydev Posted May 23, 2018 Share Posted May 23, 2018 (edited) Like I said in my previous example, to get the hash : $hash = $pages->get('/passwords/')->password->hash; Install TracyDebugger (or use var_dump() on $hash) and try my code posted earlier. You will see the hash and the salt. Edited May 23, 2018 by flydev image Link to comment Share on other sites More sharing options...
hberg539 Posted May 23, 2018 Author Share Posted May 23, 2018 Maybe i don't get it, but the user input isn't stored in a page. My user input comes from $input->post, and this value needs to be hashed/salted. Then the hashed/salted user input is put into the selector. Like: $hashed_password = magic_hash_function($input->post->password); $res = $pages->find("template=xxx,email=$sanitized_user,password=$hashed_password"); if ($res->count() >= 1) { echo "user/pass combination found, valid login"; }... Or do you mean i should store the user input from $input->post temporarly in a page just to receive the hash/salt? Thanks :-) Link to comment Share on other sites More sharing options...
flydev Posted May 23, 2018 Share Posted May 23, 2018 (edited) 1 hour ago, hberg539 said: Thanks. It works this way, but i need to iterate over all the pages and compare each with the user input (using the ->match() method) A quick example : $userPassword = $input->post->password; // user input foreach ($pages->get('/')->children as $p) { // iterate all pages $passwordField = $p->password; // get the password field if(!$passwordField || !$passwordField->matches($userPassword)) continue; // not authorized echo "'{$p->title}' Authorized"; } Edit: Nop, you don't need to store the user password, just check it against the password field stored in the page you are looking for. PS: We posted at the same time, let me know if you got it ? Edited May 23, 2018 by flydev 1 Link to comment Share on other sites More sharing options...
hberg539 Posted May 23, 2018 Author Share Posted May 23, 2018 Let's assume there are 100.000 entries and each login, you have to call the ->matches() method for each of the 100.000 entries. Wouldn't it be faster to just search the database with the correct hash? However, it is working the way you mentioned it. Thanks! Link to comment Share on other sites More sharing options...
flydev Posted May 23, 2018 Share Posted May 23, 2018 Yes it could be faster optimizing the query but it could depend on the approach used on your pages tree. In this specific case I think you could do something already solid with the pw api. When you have a moment, you can take a look at this discussion and module (the old thread). 1 Link to comment Share on other sites More sharing options...
Robin S Posted May 24, 2018 Share Posted May 24, 2018 This works for me (using the core "pass" field in the user template)... $u = $pages->get("template=user, pass=$hash"); Alternatively there's nothing wrong with using a SQL query to match data from the password field table directly if that suits you better. Link to comment Share on other sites More sharing options...
alxndre Posted May 24, 2018 Share Posted May 24, 2018 5 minutes ago, Robin S said: This works for me (using the core "pass" field in the user template)... $u = $pages->get("template=user, pass=$hash"); Alternatively there's nothing wrong with using a SQL query to match data from the password field table directly if that suits you better. I think his problem is how to get the value for $hash. // $hash = ????; $hash = howToHashThePlain('password1337'); $u = $pages->get("template=user, pass=$hash"); I'm trying to figure it out as well but most of the related things (salts, functions matches and hash) are set to protected, so I'm thinking this could not be done without touching the core modules, or extending/duplicating them to support generating the hash for the field on-the-fly. I'll perform more tests when I could. ? On a side note, I could not imagine a practical use case where you -should- be using the password field to search for members given that passwords are not meant to be unique or indicative of anything. So if OP could enlighten us on how he's using this, maybe we could be motivated to work on it more. ? Link to comment Share on other sites More sharing options...
Robin S Posted May 24, 2018 Share Posted May 24, 2018 3 minutes ago, alxndre said: I think his problem is how to get the value for $hash. Right. I don't think that's possible. By design (for security) PW generates one of the salts randomly when the password is saved so you cannot recreate a hash later that will match without having the salt that is stored along with the hash in the password field table. But typically you would have some other data available to get the relevant row from the password table. So you match to the page using some identifier like a username, then look up the row using the page ID (assuming you are doing it with SQL rather than using PW methods). So in the OP's example there is "user=abc" so that should be used first to match the relevant page rather than looping over all user pages. 1 Link to comment Share on other sites More sharing options...
hberg539 Posted May 25, 2018 Author Share Posted May 25, 2018 On 5/24/2018 at 2:55 AM, alxndre said: On a side note, I could not imagine a practical use case where you -should- be using the password field to search for members given that passwords are not meant to be unique or indicative of anything. So if OP could enlighten us on how he's using this, maybe we could be motivated to work on it more. ? Oh, you are right. I really had an error of thought with my example of iteration over 100.000 posts. The unique identifier (email address) reduces the selection to only one entry, so the ->matches() method really is no problem here. It seems i had a dangerously low level of coffeine while writing this. On 5/24/2018 at 3:11 AM, Robin S said: Right. I don't think that's possible. By design (for security) PW generates one of the salts randomly when the password is saved so you cannot recreate a hash later that will match without having the salt that is stored along with the hash in the password field table. Thanks for the explanation. Link to comment Share on other sites More sharing options...
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