PHP-Auth
PHP-Auth copied to clipboard
Confirm account if need.
Hello, I want to use the library to manage users of an app with the following registration cases and I would know if is possible and if is correct.
-
Registration by the user then classic procedure.
-
Registration by admin
For the second method I have this 2 possible case:
- I have email and I want create an account with email verification with a password random that will be changed from the user.
try {
$user_id = $app->auth()->registerWithUniqueUsername($email, $password, $username, function ($selector, $token) {
// Send email with url confirmation and username and password.
});
}
-
I don't have the email so I use a random unique email tstamp@temp I create the account but I don't send the email. When I have the correct email I change the email and use the resend confirmation email.
-
I create the account
$email = 1234556@temp
try {
$user_id = $app->auth()->registerWithUniqueUsername($email, $password, $username, function ($selector, $token) {
});
}
When I have the email I update the email, generate a random password and update it and resend confirmation with username and password
$username = 'username';
$password = 'password';
try {
$app->auth()->admin()->changePasswordForUserById($user_id, $password);
$update_users = $app->db()->update(
'users', [
'email' => $email
],
[ 'id' => $user_id]
);
$app->auth()->resendConfirmationForUserId($user_id, function ($selector, $token) use ($username, $password, $email, $app){
// SEND EMAIL WITH URL CONFIRMATION USERNAME AND PASSWORD
});
}
Everything seems work but in last method the resend give me the exception too many requests
Is possible this procedure and if yes why I have this issue.
P.S. I read that there isn't a method for change email from admin but need to login as user and change the email. But this way should to work.
Thanks!
Registration by the user then classic procedure.
Works, obviously.
I have email and I want create an account with email verification with a password random that will be changed from the user.
You use Auth#register or Auth#registerWithUniqueUsername as usual, but instead of asking the user for a password and providing it to this method, you use something like \Delight\Auth\Auth::createRandomString(16) as the initial password. You include the random password in the email for the email verification. Later password changes work as usual.
I don't have the email so I use a random unique email tstamp@temp I create the account but I don't send the email. When I have the correct email I change the email and use the resend confirmation email.
You use Auth#register or Auth#registerWithUniqueUsername as usual, but instead of asking the user for their email address and providing it to this method, you use something like \Delight\Auth\Auth::createUuid() . '@localhost' (or '@users.example.com') as the initial email address. You remove the callback parameter to have the accounts activated immediately. Later changes of the email address work as usual.
I create the account […] When I have the email I update the email, generate a random password and update it and resend confirmation with username and password
So here you have neither the email address nor the password? Why not combine the previous two approaches and use Auth#forgotPassword to allow setting a custom password later (which allows a change of the email address by you at any time, or by the user after that)?
You can’t use Database#update and then Auth#resendConfirmationForUserId. The former will not create the necessary confirmation request for the latter. That’s exactly why you’d have to sign in as the user and use Auth#changeEmail instead of Database#update.
Does this help?
I'm sorry to comment on the post again but I can't find a solution or better a correct solution.
- I am authenticated as an administrator and I create a user but I want to verify if that email is correct.
First - I add the user and send the email confirmation.
$user_id = $app->auth()->registerWithUniqueUsername($email, $password, $username, function ($selector, $token) {
//echo 'Send ' . $selector . ' and ' . $token . ' to the user (e.g. via email)';
});
Second - If the user didn't receive the email I can resend to him a confirmation email.
try {
$app->auth()->resendConfirmationForUserId($user_id, function ($selector, $token) {
echo 'Send ' . $selector . ' and ' . $token . ' to the user (e.g. via email)';
});
}
Well after this second attempt if an error is generated for sending the email (can be) I can no longer send a reconfirmation because it gives me error of too many requests. what should I do ?
- The need to use a registration by an administrator is because I want to use users for an appointment system. So not everyone will register online. Probably the appointment could be generated by phone and later the user will be activated for online access.
So here you have neither the email address nor the password? Why not combine the previous two approaches and use Auth#forgotPassword to allow setting a custom password later (which allows a change of the email address by you at any time, or by the user after that)?
As soon as I have the correct email I should to update the field email and I should to confirm if is correct, if I can't use Database#update what I should to use ?
Thanks.
Regarding your first problem, is sending two emails within a short period of time not enough? How many attempts to you want to make? You have one email sent after Auth#registerWithUniqueUsername and one sent after Auth#resendConfirmationForUserId. If the user didn’t get either of those emails, don’t you think it would be a better idea to wait a little bit before trying yet another one?
As for your second problem, as stated in my previous comment, you should use Auth#changeEmail instead of Database#update.
Regarding your first problem, is sending two emails within a short period of time not enough? How many attempts to you want to make?
Said in this way it seems strange. If I have a simple process like add user then yes seems strange, but if for example I have to add the user and add him to multiple groups with extra fields and the rollback in loop doesn't work then it is a problem.
In this case the sending email I have to do at the end, only when all the processes are completed correctly or otherwise I have to delete the user and therefore there is no need to send the email.
Maybe it's my mistake but I can't find any other alternative to register a user and ensure that all the processes conditioned by create a user are completed.
Then I tried to change the throttling deadline, put it expired but it always gives me the error. This let me think that if I don't use a function to delete all the expired throttling it doesn' t allow me to send a new reconfirmation. It's correct ?
However, an administrator should be authorized to send without being counted by throttling as it is an authoritative source and should not be considered an attempt.
As for your second problem, as stated in my previous comment, you should use Auth#changeEmail instead of Database#update
Yes I thought about this solution and I searched in the documentation and in all the posts to understand how to impersonate the user then change the email and return identified as administrator. In particular this let me log out as administrator ?
try {
$auth->admin()->logInAsUserById($_POST['id']);
}
Now I can make a change password after completed I need to logout as user and/or how I come back as admin ?
Kindly can you give me an example or where to find it?
Anyway, I don't want to disturb you too much. I love this repository and I will be looking for some workarounds to complete my process.
Thanks
Hi @ocram thanks I follow your suggestion and finally I found a working way. In few word
If the admin create an account with temp email I change the email as user and so send confirmation.
$auth->admin()->logInAsUserById($user_id]);
$auth->changeEmail($newEmail, function ($selector, $token) {
echo 'Send ' . $selector . ' and ' . $token . ' to the user (e.g. via email to the *new* address)';
});
For brb as admin I need to logout and than login as admin ?
Than if there is a mistake in typing the email if try to change receive the error too many request how can change it ?
1 mistake can easy to happen.
Thanks.
So it’s really only the case without an initial email address that’s still unclear, right? That is, the following scenario:
You use
Auth#registerorAuth#registerWithUniqueUsernameas usual, but instead of asking the user for their email address and providing it to this method, you use something like\Delight\Auth\Auth::createUuid() . '@localhost'(or'@users.example.com') as the initial email address. You remove the callback parameter to have the accounts activated immediately. Later changes of the email address work as usual.
Is that correct?
So you can certainly let the user sign in and allow them to change their own email address via Auth#changeEmail, replacing the placeholder address with their actual address.
On the other hand, if you as an admin want to set a user’s email address, you could indeed combine Auth#admin#logInAsUserById with Auth#changeEmail (and Auth#logOut) to do that.
For brb as admin I need to logout and than login as admin ?
Could you explain this again?
Than if there is a mistake in typing the email if try to change receive the error too many request how can change it ?
So you (or the user) used Auth#changeEmail to replace the placeholder address with the actual email address, but you (or the user) made a mistake, and now you want to change it again (to yet another address), right?
Indeed, the library currently allows only 1 attempt to change one’s email address every 24–72 hours. That may not be sufficient, not even in the regular use case, because the user may have made a mistake when using that one attempt, as you said. So perhaps we should just increase that to initially allow for 2–3 attempts. Do you think that would be a solution here?
@ocram Thanks for your answer always clear and detailed.
Maybe I didn't understand well the working of Auth#admin#logInAsUserById.
When an Admin login as user happen a switch account ? I mean there is an logout as Admin and a login as User ? when the admin AS user changed the email and would to come back, so terminate logInAsUserById and come back as Admin what should to make logout as user and login as Admin ?
Well what is not clear for me, after Auth#admin#logInAsUserById end the impersonation of the user and return to the role of administrator.
So perhaps we should just increase that to initially allow for 2–3 attempts. Do you think that would be a solution here?
I think that give 2 or 3 attempts and than after 24 hour is closer to the needs of normal use. If a user makes a mistake in typing an email and has to wait 24/72 hours, he is completely blocked from using the application.
PS I saw in auth in developing is possible disable the throttling when is created the instance there is a method in Foundation that there is already the instance... $app->auth() ?
Thanks
When an Admin login as user happen a switch account ? I mean there is an logout as Admin and a login as User ? when the admin AS user changed the email and would to come back, so terminate logInAsUserById and come back as Admin what should to make logout as user and login as Admin ?
Well what is not clear for me, after Auth#admin#logInAsUserById end the impersonation of the user and return to the role of administrator.
Sorry, I didn’t explain that specific part, and it’s not in the README, either.
When you’re already logged in, you can either log out first, or directly log in as another user. It doesn’t matter. Both have the same result, and that is (currently) that you’re only logged in as the second user (from the later login) now.
That’s all, though. There is no function yet that allows you to easily return to the first account. That feature specifically is tracked in this separate issue. There’s also a proposed (unofficial) solution.
Other than that, you’d have to perform a normal login as the admin again when you want to switch back. Sorry for that.
I think that give 2 or 3 attempts and than after 24 hour is closer to the needs of normal use. If a user makes a mistake in typing an email and has to wait 24/72 hours, he is completely blocked from using the application.
One side effect would be that it would allow for multiple requests (changes to different email addresses) at the same time. And when one request is confirmed, any other open request could still be confirmed after that and the email would change again. Not sure how we should handle that. Perhaps we should throw away any pending requests for email changes when one of those requests has been confirmed.
PS I saw in auth in developing is possible disable the throttling when is created the instance there is a method in Foundation that there is already the instance... $app->auth() ?
Again, sorry for that, you’re totally right: Throttling cannot be disabled yet in Foundation because the instance is already created for you there, as you said. So you can either temporarily modify the source code of Foundation to make it work. To do that, open vendor/delight-im/foundation-core/src/App.php in your project folder and (roughly in line 111, depending on your version) change the constructor arguments for $this->auth = new Auth. Or, create an issue there please so that we track the feature there and add it to Foundation as well. For example, we could automatically disable throttling whenever debug mode is active.