Skip to content

Commit 616aec4

Browse files
committed
Fix up TokenLink.
1 parent ad0e82f commit 616aec4

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

docs/Authentication/LoginLink.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ $service->loadIdentifier('Tools.LoginLink', [
2525

2626
// Session, Form, Cookie first
2727
$service->loadAuthenticator('Tools.LoginLink', [
28-
'url' => Router::url([
28+
'loginUrl' => [
2929
'prefix' => false,
3030
'plugin' => false,
3131
'controller' => 'Account',
3232
'action' => 'login',
33-
]),
33+
),
3434
]);
3535
```
3636

@@ -57,3 +57,31 @@ $service->loadIdentifier('Tools.LoginLink', [
5757
},
5858
]);
5959
```
60+
61+
Here you want to additionally confirm that the email matches. So make sure to add that to the Token content:
62+
```php
63+
$token = TableRegistry::getTableLocator()->get('Tools.Tokens')
64+
->newKey('login_link', null, $user->id, $user->email);
65+
```
66+
67+
### Sending mails via queue
68+
It is highly advised to do any (email) sending here via queue.
69+
Just add the `$token` into it and you are good to go:
70+
```
71+
$queuedJobsTable = TableRegistry::getTableLocator()->get('Queue.QueuedJobs');
72+
$token = ...;
73+
$email = $user->email;
74+
$data = [
75+
'to' => $user->email,
76+
'toName' => $user->full_name,
77+
'subject' => __('Login link'),
78+
'template' => 'login_link',
79+
'vars' => compact('email', 'token'),
80+
];
81+
$queuedJobsTable->createJob('Email', $data); // Your Email queue task
82+
```
83+
84+
Put this in the email template (linking to your login action):
85+
```php
86+
<?= $this->Url->build(['controller' => 'Account', 'action' => 'login', '?' => ['token' => $token]], ['fullBase' => true]) ?>
87+
```

src/Authenticator/LoginLinkAuthenticator.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class LoginLinkAuthenticator extends AbstractAuthenticator {
1515
* @var array<string, mixed>
1616
*/
1717
protected array $_defaultConfig = [
18-
'url' => null,
18+
'loginUrl' => null,
1919
'oneTime' => true,
2020
'queryString' => 'token',
2121
'identifierKey' => 'id',
@@ -46,12 +46,18 @@ public function authenticate(ServerRequestInterface $request): ResultInterface {
4646
*/
4747
protected function getToken(ServerRequestInterface $request): ?string {
4848
/** @var array<string, mixed> $url */
49-
$url = $this->getConfig('url');
49+
$url = $this->getConfig('loginUrl');
5050
if ($url) {
51-
$params = $request->getQuery('params');
52-
if ($params['controller'] !== $url['controller'] || $params['action'] !== $url['action']) {
51+
if (is_string($url) && $url !== $request->getUri()->getPath()) {
5352
return null;
5453
}
54+
55+
if (is_array($url)) {
56+
$params = $request->getAttribute('params');
57+
if (!$params || $params['controller'] !== $url['controller'] || $params['action'] !== $url['action']) {
58+
return null;
59+
}
60+
}
5561
}
5662

5763
return $request->getQuery('token');

0 commit comments

Comments
 (0)