Web login via NFC tag

user extended field with name KEY

So in the plugin you get a variable $user which is already the correct MODX user.

Then with

$profile = $user->getOne('Profile');

you can access the user profile and with

$extended = $profile->get('extended');

the extended field.

$extended['KEY']

should then give you the “key ID” that you can compare with the variable $password.

Ok I got php code that obtains user username or id. How can I log this user to web context?

For frontend login usually the extra Login is used.

I mean using php code.

Here is a simple code I use on a rest endpoint to login from a Vue page:

public function post() {
    $properties = $this->getProperties();

    $properties = array(
      'login_context' => 'web',
      'username'      => $properties['username'],
      'password'      => $properties['password'],
      'returnUrl'     => "/",
      'rememberme'    => 0,
    );

    $rawResponse = $this->modx->runProcessor('security/login', $properties);
    $response = $rawResponse->getResponse();
    if (!$rawResponse->response["success"]) {
      return $this->failed('Failed login', $response->getResponse(), 401);
    } 


    return $this->success('Login executed',$response->getResponse());
  }

Create a new plugin that runs on the event OnWebAuthentication, like decribed in the article that is linked in the first answer.

I read the article several times but still dont know how to pass specified user to login. So far I only have snippet that return user object.

You don’t have to do that.

You use the Login extra. The Login extra executes the security/login processor. The processor invokes the event OnWebAuthentication and gives you the user object as a parameter.

But I dont use username or password to login, but custom field in user profile ( Bobs ClassExtender ). So if I pass custom key parameter to Login extra is it also passed to plugin with event OnwebAuthentication?

The security/login processor takes the username from the login form and searches for a matching user in the database. If there is such a user, it calls OnwebAuthentication with this user and the value of the password from the login form (parameter $password).


If you don’t use the username from the modUser table as well, then you probably have to extend the class \MODX\Revolution\Processors\Security\Login (particularly the function getUser()) like it is done in the Login extra (to allow login via email-address):

Ok modify Login snippet to use different field instead of email seems like way to go. How do I create this extension without modify login snippet?

I found this article about magic links, which is similar to what I am trying to acomplish.
Logging users in to MODX with magic links | Nathanael McMillan
But there is problem in the code, maybe not working in modx 3?

in modx log:

[2023-03-17 13:30:11] (ERROR @ C:\xampp\htdocs\core\vendor\xpdo\xpdo\src\xPDO\xPDO.php : 666) Could not load class: MagicToken from mysql.magictoken

I always got stuck on
$modx->getObject(‘MagicToken’ or
$modx->newObject(‘MagicToken’
It always return null

Did you create this class “MagicToken”? Did you create it in MODX 3?
In MODX 3, all classes need a namespace. So you have to change the schema from the article you linked.

I changed the schema like this:

<?xml version="1.0" encoding="UTF-8"?>

<model package="Magiclink\Model\" baseClass="xPDO\Om\xPDOObject" platform="mysql" defaultEngine="InnoDB" phpdoc-package="" phpdoc-subpackage="" version="3.0">

      <object class="MagicToken" table="magiclink_tokens" extends="xPDOSimpleObject">
        <field key="token" dbtype="varchar" phptype="string" precision="50" null="false" default="" />
        <field key="userid" dbtype="int" phptype="int" precision="20" null="false" default="" />        
    	<field key="expires" dbtype="datetime" phptype="datetime" null="true" />
    </object>

</model>

I also noticed that path to model is magiclink/src/Model , but in php code it is only magiclink/model

So in the code you should now use

$modx->getObject('Magiclink\\Model\\MagicToken', ...);

or

use Magiclink\Model\MagicToken;

$modx->getObject(MagicToken::class, ...);

Yes, this has changed as well from MODX 2.x to MODX 3.

   $Token = $modx->getObject('Magiclink\\Model\\MagicToken', [
                    'token' => urldecode($request['token'])
                ]);

Token is still null…
do I have to modify the path somewhere else ( /src/) except first line?


// Load in our magiclink package 
$path = $modx->getOption('magiclink.core_path', null, $modx->getOption('core_path')) . 'components/magiclink/src/Model/';
$magiclink = $modx->addPackage('magiclink', $path);

I believe this should work:

$path = $modx->getOption('magiclink.core_path', null, $modx->getOption('core_path')) . 'components/magiclink/src/';
$modx->addPackage('Magiclink\Model', $path, null, 'Magiclink\\');

thanks,
but no change…