Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Email Auth Methods #230

Open
Kulltero opened this issue Sep 24, 2020 · 2 comments
Open

Adding Email Auth Methods #230

Kulltero opened this issue Sep 24, 2020 · 2 comments

Comments

@Kulltero
Copy link

Email auth or Confirm-By-Email

^ is something that i believe would be a fairly great enhancement for PHP-Auth, especially because its allready built in (in a way),
i've bee using PHP-Auth more and more to make the most ouf the library, and while it helped me find unique (and better) solutions to my problems, i've allways had the feeling that it was missing something in this area.

PHP-Auth allready has an email Confirmation system that can be used during registration (and changing email), but for any other function there is no easy method to use this email confirmation system for any other functions

Use cases for Email Confirmations

  1. Login Confirmation/device authorization
  2. Verification Methods for Critical Actions (especially Data Compliance such as deleting an account)
  3. Securely grant Access to third parties

Currently if someone wants to implement any of these cases above they have to make their own implementation of a token system or add another dependency. the issue i see is that PHP-Auth allready has a robust system for this including expiry and throttling, yet has no viable option to make use of it beyond the fixed methods.

i'm not saying PHP-Auth Should become a Do-it-All Authentication Framework, but given that the code is already there, adding the functions to make this more generally useable can be a great addition to PHP-Auth.
because afterall:

Building your own authentication classes piece by piece, and copying it to every project, is not recommended, either.

Note; while i am calling it Email Auth, i mainly mean the Selector-Token Authentication system thats used for confirming emails. i imagine a handy function to allow this for custom actions can be made similliar to the Throtte Utility that already gives us that option for Throttling Users

@ocram
Copy link
Contributor

ocram commented Sep 30, 2020

You are right. Thanks!

While the library already provides methods for generating random tokens and for throttling, and you would only have to store that token in a custom database table with a custom expiry time (and thus a custom implementation wouldn’t be too hard), why not offer additional methods to make this even easier. It fits within the scope of the library.

There’s one problem, though: With email verification after signing up, we can actually monitor and control if it’s successful and accept or reject further actions. But with your custom actions and targets, we can’t. Well, for (1) we certainly could, for (2) perhaps, but for anything else, probably not.

So that would be up to you again. And your own code and the library would have to work together in some way. So is there any API you would propose to implement the access checks after the supposed confirmation? When you want to delete an account, you would ask the library to generate a confirmation request and send the token via email. And then? How would you want to query the library for the result? Would it work for you if you could ask the library for the state of confirmation for a certain user ID and a given action described by a string, e.g. (42, change_profile_picture)?

@Kulltero
Copy link
Author

thats a good question,

i tried looking at the docs to see if i can find a fitting solution, and i think the model of how password resets work makes sense (create the token, check if its valid, do the thing (and mark token as checked)), so i thought using that would work

but once i looked at the code itself i noticed that password resets had their own specific table, so adding a new table for these general tokens would seem to be required anyways.

options:
theres the option to not implement checking if a token was confirmed and just offering this as kind of a Utility and not as a full feature

$auth->CreateToken(function($selector, $token){
    // make magic happen and forward it to the user
});
...
try {
    $auth->CheckToken($selector, $token);
    // do the thing
}
catch (\Delight\Auth\InvalidSelectorTokenPairException $e) {
    die('Invalid token');
}
catch (\Delight\Auth\TokenExpiredException $e) {
    die('Token expired');
}

but since checking completion is something alot of usecases rely on it is a good idea to have the library take care of it.

theres the option to base it completely on named selectors as you suggested, this would make it especially viable for 2-step authentications like confirming a login via a 6-digit code, if the creation function had a flag for this (making it shorter and numeric, but giving it a really short expiry time like 5 - 15 minutes).
this could make checking a token and acting based on its state really easy.

$auth->CreateAction($id, $action, $short, function($token){ // $short being the flag to make it human-friendly
    // make magic happen and forward it to the user
});
...
try {
    $confirmed = $auth->CheckAction($id,$action, $token); // and $auth->ConfirmAction(); or $auth->CheckAndConfirmAction()
    if($confirmed){
        // tell the user its confirmed, do some stuff if necessary
    }
   // do the thing or ask user for information
}
catch (\Delight\Auth\InvalidActionTokenPairException $e) {
    die('Invalid Action');
}
catch (\Delight\Auth\InvalidActionException $e) {
    die('Invalid token');
}
catch (\Delight\Auth\TokenExpiredException $e) {
    die('Token expired');
}

with the example above it may beable to provide more clarity and allow human readable varients that will work well with SPAs,
it also works well with the 3 step system that is benefitial when requireing user input after confirming an action (like information change requests).
a downside would be that the ID would have to be known making the third usecase a bit difficult to implement, but since the id is only a selector, it could also be a random string like in the existing implementation but this may make the first point invalid

i believe the second option is more versatile but i'm unsure what the best way is to directly implement the API as even when adding flags to make it more versatile it will allways have cases where it may be restrictive as in:

  • what if we want 4 digits?
  • what if we want a longer expiry?
  • what if we want more states?
  • what if i just want a random token? no selectors just check if the token exists?

adding flags or customisability can solve all this, but i like the beauty of how the library keeps its method pretty general, so i havent yet found an elegant way for this.

the first option was my initial thought as it seemed simple, but i had not dug thoroughly through the library to see how its currently implemented. so after thinking on it more the second option is more favorable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants