yii2会话未保存来自邮递员/应用的登录信息

时间:2018-11-15 04:08:54

标签: php yii2

我正在yii2框架中为我的网站使用前端模块,到目前为止,该网站对于所有事情都工作良好,尤其是从Web界面登录的会话。

处理登录的模型是LoginForm模型

    namespace app\models;

    use Yii;
    use yii\base\Model; 

    /**
     * Login form 
     */
    class LoginForm extends Model {
        public function login()
        {
            if ($this->validate()) {
                return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 7200 * 24 * 30 : 7200 * 24 * 30);
            }

            return false;
        }

对于网站,默认的登录文件位于SiteCotroller.php

        use yii\web\Controller;
        use frontend\models\ContactForm;

        /**
         * Site controller
         */
        class SiteController extends Controller {
            /**
             * @inheritdoc
             */
            public function behaviors() {
                return [
                    'access' => [
                        'class' => AccessControl::className(),
                        'only' => ['logout', 'signup', 'index'],
                        'rules' => [
                            [
                                'actions' => ['signup'],
                                'allow' => true,
                                'roles' => ['?'],
                            ],
                            [
                                'actions' => ['logout', 'index'],
                                'allow' => true,
                                'roles' => ['@'],
                            ],
                        ],
                    ],
                    'verbs' => [
                        'class' => VerbFilter::className(),
                        'actions' => [
                            'logout' => ['post'],
                        ],
                    ],
                ];
            }
            public function actionLogin() {
                $this->layout = 'main';

                if (!Yii::$app->user->isGuest) {
                    return $this->goHome();
                }

                $model = new LoginForm();
                if ($model->load(Yii::$app->request->post()) && $model->login()) {
                    return $this->goBack();
                } else {
                    return $this->render('login', [
                        'model' => $model,
                    ]);
                }
            }

        }

在视图文件中,登录控制器非常适合自己的界面。



现在,我想从应用程序(离子/角度)访问登录名,我将该控制器的登录名复制到相似的前端文件夹中的AppController.php中:

    class AppController extends \yii\rest\Controller {

        public function actions() 
        {
            $actions = parent::actions();
            $actions['options'] = [
                'class' => 'yii\rest\OptionsAction',
                // optional:
                'collectionOptions' => ['GET', 'POST', 'HEAD', 'OPTIONS'],
                'resourceOptions' => ['GET', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
            ];
            return $actions;
        }

        public function actionIndex() {
            echo json_encode("hi"); 
        }

        public static function allowedDomains() {
            return [
                 '*',                        // star allows all domains
                'http://localhost:8100',
                //'http://test2.example.com',
            ];
        }

        public function init()
        {
            parent::init();
            \Yii::$app->user->enableSession = false;
        }

        public function beforeAction($action)
        {
            $this->enableCsrfValidation = false;


            return parent::beforeAction($action);
        }

        public function behaviors()
        {
            $behaviors = parent::behaviors();
            unset($behaviors['authenticator']);

            // add CORS filter
            $behaviors['corsFilter'] = [
                'class' => \yii\filters\Cors::className(),
                'cors' => [
                    'Origin' => ['*'],
                    'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
                    'Access-Control-Request-Headers' => ['*'],
                    'Access-Control-Allow-Credentials' => true,
                ],
            ];

            $behaviors['contentNegotiator'] = [
                'class' => \yii\filters\ContentNegotiator::className(),
                'formats' => [
                    'application/json' => \yii\web\Response::FORMAT_JSON,
                ],
            ];

            $behaviors['authenticator'] = [
                'class' => HttpBearerAuth::className(),
                'except' => ['login', 'checkuser'],   

                /*
                'class' => CompositeAuth::className(),
                'authMethods' => [
                    HttpBasicAuth::className(),

                ],
                'except' => ['login', 'checkuser'],
                */

            ];

            return $behaviors;
        }


        public function actionLogin() {

            $model = new LoginForm();
            $params = Yii::$app->request->post();
            $model->username = $params['username'];
            $model->password = $params['password'];

            if ($model->login()) {
                $user = User::findByUsername($model->username);
                $response['success'] = Yii::$app->user->login($user);
                $response['SessionID'] = Yii::$app->session->getId();
                return $response; 
            } else {
                $response['errors'] = $model->getErrors();
                return $response;
            }
        }

奇怪的是,如果我尝试从app / postman登录,则此AppController.php中的操作登录有效,它返回true。但是,不会保存该会话,并且SessionID为空。

我已经研究了三天,但仍然无法弄清问题出在哪里。

这是我的frontend / config / main.php文件

        $params = array_merge(
            require __DIR__ . '/../../common/config/params.php',
            require __DIR__ . '/../../common/config/params-local.php',
            require __DIR__ . '/params.php',
            require __DIR__ . '/params-local.php'
        );

        return [
            'id' => 'app-frontend',
            'defaultRoute' => 'site/index',
            'basePath' => dirname(__DIR__),
            'bootstrap' => ['log', 'gii'],
            'controllerNamespace' => 'frontend\controllers',
            'layout' => 'admin',
            'components' => [ 
                'request' => [
                    'parsers' => [
                        'application/json' => 'yii\web\JsonParser',
                    ], 
                    'csrfParam' => '_csrf-frontend',
                ],
                'user' => [
                    'identityClass' => 'app\models\User',
                    'enableAutoLogin' => false,
                    'enableSession' => true,
                    'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true, 'lifetime' => 3600 * 4],
                    'loginUrl' => ['site/login'],
                ],
                'session' => [
                    'name' => 'advanced-frontend',
                ],

enter image description here

当我直接访问yii2网络域中的URL时,我在浏览器Cookies中得到了这个_csrf-frontendadvanced-frontend值。但是从应用程序我什么也没得到。

请非常感谢您的帮助。提前谢谢了。

1 个答案:

答案 0 :(得分:0)

您无法从绑定到域的另一个应用程序检索会话。因此,您可能应该做的是在Ionic应用程序中单独处理该逻辑,我认为这是首选方法。或者,您可以通过将会话存储在数据库中(为此有Yii类)来实现,而不是通过额外的请求来处理它(这是不好的方法)。