yii2-usuario
yii2-usuario copied to clipboard
Problem with authorization through social network new user. Return 404
https://github.com/2amigos/yii2-usuario/blob/8adbffeb3f2da4e2bd77be8d7e06a1629904734f/src/User/Controller/RegistrationController.php#L158
Pls, help me. The problem with authorization through social network new user. Return 404 /user/registration/connect?code=FMwHPLCI*****************DJC
// Da\User\Controller\RegistrationController
public function actionConnect($code)
{
/** @var SocialNetworkAccount $account */
$account = $this->socialNetworkAccountQuery->whereCode($code)->one();
if ($account === null || $account->getIsConnected()) {
throw new NotFoundHttpException(); // !!!!!!!!!! social_account not saved
}
...
}
// Da\User\Service\SocialNetworkAuthenticateService
protected function createAccount()
{
$data = $this->client->getUserAttributes();
/** @var SocialNetworkAccount $account */
$account = $this->controller->make(
SocialNetworkAccount::class,
[],
[
'provider' => $this->client->getId(),
'client_id' => $data['id'],
'data' => json_encode($data),
'username' => $this->client->getUserName(),
'email' => $this->client->getEmail(),
]
);
// !!!!!!!!!!!!!!!!! User not found => social_account not save
if (($user = $this->getUser($account)) instanceof User) {
$account->user_id = $user->id;
$account->save(false);
}
return $account;
}
I tried all events. The problem is solved only this way, otherwise redirecting to 404
Config. Event beforeAuthenticate handler
'user' => [
'class' => Da\User\Module::class,
'controllerMap' => [
'security' => [
'class' => 'Da\User\Controller\SecurityController',
'on beforeAuthenticate' => ['app\components\SocialNetworkHandler', 'beforeAuthenticate']
],
],
],
file components/SocialNetworkHandler.php
<?php
namespace app\components;
use Da\User\Event\SocialNetworkAuthEvent;
use Da\User\Factory\MailFactory;
use Da\User\Model\User;
use Da\User\Service\UserCreateService;
use Yii;
use yii\base\BaseObject;
class SocialNetworkHandler extends BaseObject
{
/**
* @param SocialNetworkAuthEvent $event
*/
public static function beforeAuthenticate($event)
{
/** @var User $model */
$user = Yii::$container->get(User::class);
if($user::find()->where(['email' => $event->client->email])->exists()) return;
$user = new $user([
'scenario' => 'create',
'email' => $event->client->email,
'username' => $event->client->username,
'password' => null
]);
/** @var MailFactory $mailFactory */
$mailFactory = Yii::$container->get(MailFactory::class);
$mailService = $mailFactory::makeWelcomeMailerService($user);
/** @var UserCreateService $userCreateService */
$userCreateService = Yii::$container->get(UserCreateService::class, [$user, $mailService]);
$userCreateService->run();
$event->account->user_id = $user->id;
$event->account->save();
Yii::$app->user->login($user);
}
}
I also noticed this bug.
i fixed it moving save(false)
outside the IF statement. ugly fix though.
BEFORE
if (($user = $this->getUser($account)) instanceof User) {
$account->user_id = $user->id;
$account->save(false);
}
AFTER
if (($user = $this->getUser($account)) instanceof User) {
$account->user_id = $user->id;
}
$account->save(false);
@grozzzny from your code I made an even simpler fix. Thanks for the insight on the beforeAuthenticate hook. My final SocialNetworkHandler.php file is only the code below. Rest is exactly the same as you pointed out.
class SocialNetworkHandler extends BaseObject
{
/**
* @param SocialNetworkAuthEvent $event
*/
public static function beforeAuthenticate($event)
{
return $event->account->save(false);
}
}
Saving the social account like above already unlocks the entire user registration/welcome email etc. stuff existing, in my project the code below is redundant ( of course, unless you are customizing it)
$user = new $user([
'scenario' => 'create',
'email' => $event->client->email,
'username' => $event->client->username,
'password' => null
]);
/** @var MailFactory $mailFactory */
$mailFactory = Yii::$container->get(MailFactory::class);
$mailService = $mailFactory::makeWelcomeMailerService($user);
/** @var UserCreateService $userCreateService */
$userCreateService = Yii::$container->get(UserCreateService::class, [$user, $mailService]);
$userCreateService->run();
```
Thanks, @mkodummy. I will test later.
@mkodummy and @grozzzny Thanks, the last change works!
But I get this warning when login with github:
Please use the Authorization HTTP header instead as using the access_token
query parameter is deprecated.
Depending on your API usage, we'll be sending you this email reminder on a monthly basis.
Visit https://developer.github.com/changes/2020-02-10-deprecating-auth-through-query-param for more information about suggested workarounds and removal dates.
Thanks so much @mkodummy and @grozzzny, it worked for me. I searched for a few hours to find this topic.
this happened to me also ... and I reached this page ... why is not fixed in the official repo ?
For PHP 7.4+
'user' => [
'class' => Da\User\Module::class,
'controllerMap' => [
'security' => [
'class' => Da\User\Controller\SecurityController::class,
'on beforeAuthenticate' =>
static fn (Da\User\Event\SocialNetworkAuthEvent $event) => $event->account->save(false),
],
],
// ...
],
This solution worked like a charm!
For PHP 7.4+
'user' => [ 'class' => Da\User\Module::class, 'controllerMap' => [ 'security' => [ 'class' => Da\User\Controller\SecurityController::class, 'on beforeAuthenticate' => static fn (Da\User\Event\SocialNetworkAuthEvent $event) => $event->account->save(false), ], ], // ... ],
For PHP 7.4+
'user' => [ 'class' => Da\User\Module::class, 'controllerMap' => [ 'security' => [ 'class' => Da\User\Controller\SecurityController::class, 'on beforeAuthenticate' => static fn (Da\User\Event\SocialNetworkAuthEvent $event) => $event->account->save(false), ], ], // ... ],
@jonyx4 @mj4444ru
I added this in my main.php
anything else to add? doesm't seem to work for me. new accounts not getting registered with social networks.
@grozzzny i tried your steps, after i login with google, it redirects me to user/registration/connect&code=adssad
how do i get it to skip that? and get fill in the firtsname lastname email etc from google
For PHP 7.4+
'user' => [ 'class' => Da\User\Module::class, 'controllerMap' => [ 'security' => [ 'class' => Da\User\Controller\SecurityController::class, 'on beforeAuthenticate' => static fn (Da\User\Event\SocialNetworkAuthEvent $event) => $event->account->save(false), ], ], // ... ],
@Jonyx4 @mj4444ru
I added this in my
main.php
anything else to add? doesm't seem to work for me. new accounts not getting registered with social networks.
I don't know if this is related to your issue, but I also had to apply the fix described in this issue https://github.com/2amigos/yii2-usuario/issues/397
@Jonyx4 unfortunately adding the return $account;
still redirects the user to user/registration/connect&code=adssad
to confirm registration. it should auto fill in firstname lastname etc into db :(
This works for me:
'security' => [
'class' => 'Da\User\Controller\SecurityController',
'on beforeAuthenticate' => ['frontend\controllers\SocialNetworkHandler', 'beforeAuthenticate']
],
frontend\controllers\SocialNetworkHandler:
namespace frontend\controllers;
use Da\User\Event\SocialNetworkAuthEvent;
use Da\User\Factory\MailFactory;
use Da\User\Model\User;
use Da\User\Service\UserCreateService;
use Yii;
use yii\base\BaseObject;
class SocialNetworkHandler extends BaseObject
{
/**
* @param SocialNetworkAuthEvent $event
*/
public static function beforeAuthenticate($event)
{
return $event->account->save(false);
}
}
@whisere does yours redirect newly registered users to the user/registration/connect
page to input their email etc after they click on the social connect button? how do i bypass that step?
It is normal that's just a step for user to confirm/edit their user name and email in the system (they may not want to use the same user name and email used in the social media account), it should automatically fill in the email address from social account.
@whisere cool, thanks. if i was to skip that step, and auto fill firstname and last name from social account, know which file i can edit or extend by any chance?
There may not be first and last name from social account, you can see: https://github.com/2amigos/yii2-usuario/tree/master/src/User/AuthClient (better to fork your own repo/copy if to make change to code)
overwriting controllers in the documentation: https://yii2-usuario.readthedocs.io/en/latest/enhancing-and-overriding/overriding-controllers/# and social events and other events under the events menu: https://yii2-usuario.readthedocs.io/en/latest/events/social-network-connect-events/
@whisere thanks. for the most part i got it working. It just doesn't seem to save the firstname and lastname in the user table. any idea what im missing here? here are the changes i made to the controller. https://github.com/2amigos/yii2-usuario/issues/418