Adding Google Authenticator #439
Conversation
steinkel
left a comment
There was a problem hiding this comment.
Please check review comments
| "require": { | ||
| "cakephp/cakephp": ">=3.2.9 <4.0.0" | ||
| "cakephp/cakephp": ">=3.2.9 <4.0.0", | ||
| "robthree/twofactorauth": "^1.5.2" |
There was a problem hiding this comment.
we should not require this lib by default, we are trying to keep the plugin as clean as possible and let every user include the required packages if needed, for example see the oauth related packages
| "league/oauth2-linkedin": "@stable", | ||
| "google/recaptcha": "@stable" | ||
| "google/recaptcha": "@stable", | ||
| "robthree/twofactorauth": "^1.5.2" |
There was a problem hiding this comment.
Is this needed here? or could we leave this as suggest only and add some docs on how to properly setup the 2factor feature?
There was a problem hiding this comment.
@steinkel , I've removed it from require param, and left it only in require-dev just to make sure that unit tests will pass.
| $table->addColumn('secret', 'string', [ | ||
| 'after' => 'activation_date', | ||
| 'default' => null, | ||
| 'limit' => 255, |
There was a problem hiding this comment.
secret is using any fixed size or should we use text instead?
| 'plugin' => 'CakeDC/Users', | ||
| 'controller' => 'Users', | ||
| 'action' => 'verify', | ||
| 'prefix' => null, |
There was a problem hiding this comment.
better to use "false" instead, to prevent issues with login inside a prefixed controller. We had issues with this before setting up the loginAction...
| const EVENT_BEFORE_LOGOUT = 'Users.Component.UsersAuth.beforeLogout'; | ||
| const EVENT_AFTER_LOGOUT = 'Users.Component.UsersAuth.afterLogout'; | ||
|
|
||
|
|
| $this->set('secretDataUri', $this->GoogleAuthenticator->getQRCodeImageAsDataUri($temporarySession['email'], $secret)); | ||
| } | ||
|
|
||
| if ($this->request->is('post')) { |
| if ($this->request->is('post')) { | ||
| $verificationCode = $this->request->data['code']; | ||
| $user = $this->request->session()->read('temporarySession'); | ||
|
|
There was a problem hiding this comment.
check user keys before using them
| $this->request->session()->write('Auth.User', $user); | ||
|
|
||
| $url = $this->Auth->redirectUrl(); | ||
|
|
| $this->Flash->error($message, 'default', [], 'auth'); | ||
|
|
||
| $this->request->session()->destroy(); | ||
|
|
| <?php if (!empty($secretDataUri)):?> | ||
| <p class='text-center'><img src="<?php echo $secretDataUri;?>"/></p> | ||
| <?php endif;?> | ||
| <?= $this->Form->input('code', ['required' => true,'label' => 'Verification Code']) ?> |
Otherwise the tests won't run
I've expanded a bit the default LoginTrait to support Google Authenticator mechanism, by using TwoFactorAuth plugin (since version 1.5.2, which became PSR-4 compatible for CakePHP3.x).
In order to function properly, there was also added migration file, to expand
userstable withsecret, secret_verifiedfields. One holds Base32 shared secret, the second one - makes sure QR-code is shown inverify.ctpuntil the first successful verification/login into the system.After the user is authorised from
/login, I'm creating temporary session, with holds all required data for me, removing Auth.Users session (to avoid access for restricted url's), and redirect to/verify, where verification process takes place. Once verification is successful, I'm restoring Auth.Users session to let AuthComponent magic to work.