Just checking, this would only be beneficial if it does not ask them initially for a password? As in, two-factor auth wouldn’t work for what you need.
Actually I found the plugin that’s already does that… But it’s 3-rd party.
[ No bumping please. ]
You can manage all of this through the ‘wp_authenticate’ action I believe.
If you like, the email sent to the user could include the one time password (or “nonce”) in a clickable link, they don’t really need to type it in again unless you just like to make things more difficult 😉
The basic logic of the action callback goes like this:
If the usual and/or one time password field is empty, send an email with the one time password/nonce to the user’s email address, then die with a “Check your email” message or similar.
If the requesting URL contains a nonce parameter, then it was a link clicked from within the sent email. Place the nonce where the usual password is in the passed by reference array. It will of course fail a normal password authentication, it’s presence is mainly to prevent the empty password validation from triggering. At this point everything seems to be in order so add a filter callback to ‘authenticate’, then return. The added filter takes care of the rest.
The authenticate filter works as it normally would, except you are checking the passed password/nonce as a nonce, not a normal password. If the nonce check succeeds, get the WP_User object for the user and return it. If the check fails, return a new WP_Error object instead.
There’s some other details to deal with, like the email needs to be sent out as HTML for the link to appear as a link, but that’s the basics.