123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- <?php
- /**
- * Created by PhpStorm.
- * User: NODELOG
- * Date: 16/7/26
- * Time: 下午4:02
- */
- namespace common\modules\user\frontend\controllers;
- use common\modules\user\models\Auth;
- use common\modules\user\models\LoginForm;
- use common\modules\user\models\PasswordResetRequestForm;
- use common\modules\user\models\ResetPasswordForm;
- use common\modules\user\models\User;
- use Yii;
- use yii\authclient\ClientInterface;
- use yii\base\InvalidParamException;
- use yii\filters\AccessControl;
- use yii\filters\VerbFilter;
- use yii\helpers\ArrayHelper;
- use yii\helpers\Url;
- use yii\web\BadRequestHttpException;
- use yii\web\Controller;
- class SecurityController extends Controller
- {
- public function behaviors()
- {
- return [
- 'access' => [
- 'class' => AccessControl::className(),
- 'only' => ['logout'],
- 'rules' => [
- [
- 'actions' => ['logout'],
- 'allow' => true,
- 'roles' => ['@'],
- ],
- ],
- ],
- 'verbs' => [
- 'class' => VerbFilter::className(),
- 'actions' => [
- 'logout' => ['post'],
- ],
- ],
- ];
- }
- public function actions()
- {
- return [
- 'auth' => [
- 'class' => 'yii\authclient\AuthAction',
- 'successCallback' => \Yii::$app->user->isGuest
- ? [$this, 'authenticate']
- : [$this, 'connect'],
- 'redirectView' => __DIR__ . '/redirect.php'
- ],
- ];
- }
- public function authenticate(ClientInterface $client)
- {
- $attributes = $client->getUserAttributes();
- $email = ArrayHelper::getValue($attributes, 'email');
- $id = ArrayHelper::getValue($attributes, 'id');
- $nickname = ArrayHelper::getValue($attributes, 'login');
- /** @var Auth $auth */
- $auth = Auth::find()->where([
- 'source' => $client->getId(),
- 'source_id' => $id,
- ])->one();
- if ($auth) { // login
- /** @var User $user */
- $user = $auth->user;
- Yii::$app->user->login($user);
- } else { // signup
- if ($email !== null && User::find()->where(['email' => $email])->exists()) {
- Yii::$app->getSession()->setFlash('error', [
- Yii::t('app', "User with the same email as in {client} account already exists but isn't linked to it. Login using email first to link it.", ['client' => $client->getTitle()]),
- ]);
- } else {
- $password = Yii::$app->security->generateRandomString(6);
- $user = new User([
- 'scenario' => 'create',
- 'username' => User::findByUsername($nickname) ? $nickname . '_' . mt_rand(1000, 9999) : $nickname,
- 'email' => $email,
- 'password' => $password,
- ]);
- $user->generateAuthKey();
- $user->generatePasswordResetToken();
- $transaction = User::getDb()->beginTransaction();
- if ($user->save()) {
- $auth = new Auth([
- 'user_id' => $user->id,
- 'source' => $client->getId(),
- 'source_id' => (string)$id,
- ]);
- if ($auth->save()) {
- $transaction->commit();
- Yii::$app->user->login($user);
- } else {
- Yii::$app->getSession()->setFlash('error', [
- Yii::t('app', 'Unable to save {client} account: {errors}', [
- 'client' => $client->getTitle(),
- 'errors' => json_encode($auth->getErrors()),
- ]),
- ]);
- }
- } else {
- Yii::$app->getSession()->setFlash('error', [
- Yii::t('app', 'Unable to save user: {errors}', [
- 'client' => $client->getTitle(),
- 'errors' => json_encode($user->getErrors()),
- ]),
- ]);
- }
- }
- }
- }
- public function connect(ClientInterface $client)
- {
- $attributes = $client->getUserAttributes();
- $id = ArrayHelper::getValue($attributes, 'id');
- /** @var Auth $auth */
- $auth = Auth::find()->where([
- 'source' => $client->getId(),
- 'source_id' => $id,
- ])->one();
- if (!$auth) { // add auth provider
- $auth = new Auth([
- 'user_id' => Yii::$app->user->id,
- 'source' => $client->getId(),
- 'source_id' => (string)$attributes['id'],
- ]);
- if ($auth->save()) {
- /** @var User $user */
- Yii::$app->getSession()->setFlash('success', [
- Yii::t('app', 'Linked {client} account.', [
- 'client' => $client->getTitle()
- ]),
- ]);
- } else {
- Yii::$app->getSession()->setFlash('error', [
- Yii::t('app', 'Unable to link {client} account: {errors}', [
- 'client' => $client->getTitle(),
- 'errors' => json_encode($auth->getErrors()),
- ]),
- ]);
- }
- } else { // there's existing auth
- Yii::$app->getSession()->setFlash('error', [
- Yii::t('app',
- 'Unable to link {client} account. There is another user using it.',
- ['client' => $client->getTitle()]),
- ]);
- }
- $this->action->successUrl = Url::to(['/user/settings/auth']);
- }
- /**
- * Logs in a user.
- *
- * @return mixed
- */
- public function actionLogin()
- {
- if (!\Yii::$app->user->isGuest) {
- return $this->goHome();
- }
- $model = new LoginForm();
- if ($model->load(Yii::$app->request->post()) && $model->login()) {
- if (Yii::$app->request->isAjax) {
- Yii::$app->response->format = 'json';
- return ['message' => '登录成功'];
- }
- return $this->goBack();
- } else {
- if (Yii::$app->request->isAjax) {
- return $this->renderAjax('login', [
- 'model' => $model,
- 'module' => $this->module
- ]);
- }
- return $this->render('login', [
- 'model' => $model,
- 'module' => $this->module
- ]);
- }
- }
- /**
- * Logs out the current user.
- *
- * @return mixed
- */
- public function actionLogout()
- {
- Yii::$app->user->logout();
- return $this->goHome();
- }
- /**
- * Requests password reset.
- *
- * @return mixed
- */
- public function actionRequestPasswordReset()
- {
- $model = new PasswordResetRequestForm();
- if ($model->load(Yii::$app->request->post()) && $model->validate()) {
- if ($model->sendEmail()) {
- Yii::$app->session->setFlash('success', '请登录邮箱重置密码');
- return $this->goHome();
- } else {
- Yii::$app->session->setFlash('error', '很抱歉,发生错误了!');
- }
- }
- return $this->render('requestPasswordResetToken', [
- 'model' => $model,
- ]);
- }
- /**
- * Resets password.
- *
- * @param string $token
- *
- * @return mixed
- *
- * @throws BadRequestHttpException
- */
- public function actionResetPassword($token)
- {
- try {
- $model = new ResetPasswordForm($token);
- } catch (InvalidParamException $e) {
- throw new BadRequestHttpException($e->getMessage());
- }
- if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {
- Yii::$app->session->setFlash('success', '新密码设置成功!');
- return $this->goHome();
- }
- return $this->render('resetPassword', [
- 'model' => $model,
- ]);
- }
- }
|