Authclient With Yii User

Hi! I am trying to develop the successCallback method of Authclient using a yii user widget.

I had installed https://github.com/amnah/yii2-user. First of all I extended the module and I change the defaultcontroller.php

  • Add action: auth

  • Create the method: successCallback()

My method successCallback() is:


public function successCallback($client)

    {

        $model = Yii::$app->getModule("user")->model("LoginForm");

        $user = Yii::$app->getModule("user")->model("User", ["scenario" => "register"]);

        $profile = Yii::$app->getModule("user")->model("Profile");


        $attributes = $client->getUserAttributes();

        if(!empty($attributes)) {

            $model->load($attributes);

            $user->load($attributes);

            $profile->load($_POST);


            if ($user->getIsNewRecord()) {

                // validate for normal request

                if ($user->validate() and $profile->validate()) {


                    // perform registration

                    /** @var \app\modules\user\models\Role $role */

                    $role = Yii::$app->getModule("user")->model("Role");

                    $user->register($role::ROLE_USER);

                    $profile->register($user->id);

                    $this->_calcEmailOrLogin($user);


                    // set flash

                    Yii::$app->session->setFlash("Register-success", $user->getDisplayName());

                }


                // render view

                return $this->render("register", [

                    'user' => $user,

                    'profile' => $profile,

                ]);

            } else {

                if ($model->login(Yii::$app->getModule("user")->loginDuration)) {

                    return $this->goHome();

                }

            }

        }


        // render view

        return $this->render('login', [

            'model' => $model,

        ]);

    }

But $client->getUserAttributes() does not return the correct values and if i remove the validation condition the user is created without username, mail, etc.

When I installed Authclient i saw that a dependency is this widget https://github.com/dektrium/yii2-user/ and may be I should change it.

Did somebody use Authclient with amnah/yii2-user ?

Thanks!!

Regarding validation, the built-in validation rules are for local registrations. If you want to add in automatic registrations using facebook/twitter/etc data, you might want to create a new scenario with corresponding validation rules. Something like $user->setScenario("register-external").

The problem with external authentication, though, is that different services will give you different data. For example, you may get email+username from facebook, but you’ll only get username from twitter (no email). You need to run through the code and see exactly what data you get from the services you need, then you can come up with a solution on how to process them.

Not sure what you meant by this … The only dependency I see is curl.

Thanks amnah! The error was how I was trying to get the attributes values of the client.

This method


$client->getUserAttributes()

return an array and googleOpenID return:

  • $attributes["email"]

  • $attributes["first_name"]

  • $attributes["last_name"]

  • $attributes["language"]

My successCallback method is:


public function successCallback($client)

    {

        $user = Yii::$app->getModule("user")->model("User");


        $attributes = $client->getUserAttributes();

        $current_user = $user::find(["email" => $attributes["email"]]);


        if ($current_user["id"] >  0) {

            $user_login = Yii::$app->getModule("user")->model("LoginForm");


            $_POST["LoginForm"]["username"] = $attributes["email"];

            $_POST["LoginForm"]["rememberMe"] = 1;


            $user_login->load($_POST);

            Yii::$app->user->login($user_login->getUser(), Yii::$app->getModule("user")->loginDuration);


        } else {

            $user->setScenario("register-external");


            $user->email = $attributes["email"];

            $user->username = strtolower($attributes["first_name"][0]).strtolower($attributes["last_name"]);

            $user->status = $user::STATUS_ACTIVE;


            $profile = Yii::$app->getModule("user")->model("Profile");

            $profile->full_name = $attributes["first_name"]." ".$attributes["last_name"];


            $role = Yii::$app->getModule("user")->model("Role");


            $user->register($role::ROLE_USER);

            $profile->register($user->id);

            $this->_calcEmailOrLogin($user);


            // set flash

            Yii::$app->session->setFlash("Register-success", $user->getDisplayName());

            $this->refresh();


            Yii::$app->user->login($user, Yii::$app->getModule("user")->loginDuration);

        }

    }

Works!

Thanks!

Thank you for posting the working version.

I think we should handle in a different way to get the attributes of the client?

Please can you explain below line? Do you have a method like getModel in your controller or module class?

$profile = Yii::$app->getModule("user")->model("Profile");

That is a helper function to make the module more extendable.

When you configure the module in config/web.php, you have the option of setting the modelClasses property. The \amnah\yii2\user\Module::model($name, $config=[]) function uses that modelClasses property to create the corresponding model.

For example:




// config/web.php

'modules' => [

    'user' => [

        // ...

        'modelClasses'  => [

            'Profile' => 'app\models\MyProfile',

        ],

        // ...

    ],

],


//so these two are equivalent

$profile = Yii::$app->getModule("user")->model("Profile");

$profile = new \app\models\MyProfile();


// though technically, it does it via Yii::createObject(), so you can pass in

// a config array for the object properties

$profile = Yii::$app->getModule("user")->model("Profile", ["property1"=>"value1"]);