Php 用于会话ip地址不工作的移动设备的Yii2 rest Api

Php 用于会话ip地址不工作的移动设备的Yii2 rest Api,php,rest,session,yii2,Php,Rest,Session,Yii2,我曾经开发过基于web的restapi,但这是我第一次为移动应用程序创建restapi。我正试图做的是发送短信代码到用户张贴的手机号码。SMS代码保存在具有用户ip地址的会话中。 下一步,用户发送短信代码。Rest API比较会话中发布的SMS代码。 这是我发送短信和验证短信的代码 //send sms code here public function actionSendSms(){ $this->response['success'] = false; $model

我曾经开发过基于web的restapi,但这是我第一次为移动应用程序创建restapi。我正试图做的是发送短信代码到用户张贴的手机号码。SMS代码保存在具有用户ip地址的会话中。 下一步,用户发送短信代码。Rest API比较会话中发布的SMS代码。 这是我发送短信和验证短信的代码

 //send sms code here
 public function actionSendSms(){
   $this->response['success'] = false;
   $model = $this->loadPostData('step1phone');
   $phone = str_replace('+','',Yii::$app->request->post('phone'));
   $model->phone = urlencode(preg_replace('/[^\d\+]/', '', $phone));
   if(Yii::$app->request->isPost && $model->validate()){
     $code = Yii::$app->helper->generateRandomString(4);
     Yii::$app->sms->setMessage($code);
     $sms = Yii::$app->sms->send($model->phone);
     if($sms->status){
        $ipAddress = Yii::$app->request->getUserIP();
        Yii::$app->session->set('phone-'.$ipAddress, $code);
        $this->response['success'] = true;
    }else{
        $this->response['errorMessage'] = $sms->errorMessage;
    }
  }else{
    $this->response['status'] = 'error';
    $this->response['errors'] = $model->getErrors(); //@TODO
  }
  return $this->response;
}
//sms code validation here
public function actionSendSmsCode()
{
    $ipAddress = Yii::$app->request->getUserIP();
    \Yii::info('User IP - '.$ipAddress, 'mylog');
    $model = $this->loadPostData('step1phoneVerify');
    if($model->validate()){
      $this->response['status'] = true;
      $this->response['data'] = [
          'code' => Yii::$app->session->get('phone-'.$ipAddress),
          'postValue' => Yii::$app->request->post('phoneVerificationCode'),
      ];
        \Yii::info('code - '.Yii::$app->session->get('phone-'.$ipAddress), 'mylog');
        \Yii::info('postValue - '.Yii::$app->request->post('phoneVerificationCode'), 'mylog');
        \Yii::info('User IP - '.Yii::$app->request->getUserIP(), 'mylog');
    }
    else
    {
        $this->response['status'] = 'error';
        $this->response['error'] = $model->getErrors();
        $this->response['data'] = [
            'code' => Yii::$app->session->get('phone-'.Yii::$app->request->getUserIP()),
            'postValue' => Yii::$app->request->post('phoneVerificationCode'),
        ];
        \Yii::info('code - '.Yii::$app->session->get('phone-'.$ipAddress), 'mylog');
        \Yii::info('postValue - '.Yii::$app->request->post('phoneVerificationCode'), 'mylog');
        \Yii::info('User IP - '.Yii::$app->request->getUserIP(), 'mylog');
    }
    \Yii::info('Session - '. json_encode(Yii::$app->session) , 'mylog');
    //$this->$this->response['session'] = Yii::$app->session->get('phone-'.$ipAddress);
    return $this->response;
}

//Model used for validation.
public function validateSmsCode($attribute, $params)
{
    $ipAddress = Yii::$app->request->getUserIP();
    if(!empty($this->phoneVerificationCode) && $this->phoneVerificationCode != Yii::$app->session->get('phone-'.$ipAddress))
    {
        $this->addError('phoneVerificationCode', Yii::t('app', 'SMS code doesn`t match.'));
    }
}
当我尝试从PostRESTAPI服务测试我的代码时,一切正常。但从手机应用程序,是永远不会得到验证,即使我张贴正确的短信代码。 当我尝试在日志文件中查看时,“code-”为空,但“User IP-”获取用户的IP地址。 注意:这里再次说明,如果我使用PostRESTAPI服务,我会在日志文件中获得例外信息。我的应用程序前端是android。有人能告诉我我做错了什么吗


感谢高级版。

您使用IP地址作为安全和静态值的错误是错误的

IP地址:每个用户的用户IP地址不是唯一的,因为数量有限,因此通常多个用户共享同一IP、NAT公共IP地址,请阅读更多有关NAT的信息,但请记住用户IP是共享的,可以更改,攻击者可以欺骗它

php会话:是通常存储在服务器上的数据(并非所有情况下都是如此)。因此,服务器向客户端发送一个密钥作为安全令牌,并且每次客户端使用cookie发送此令牌,以便服务器可以加载会话。因此,您不需要IP,因为您已经拥有安全令牌

将数据保存到会话:

Yii::$app->session->set('phone', $model->phone);
Yii::$app->session->set('code', $code);
//Just use key (static string) to store in session as this session in unique per user
$phone = Yii::$app->session->get('phone');
$code = Yii::$app->session->get('code');
//Just use key that you used to store the data
从会话读取数据:

Yii::$app->session->set('phone', $model->phone);
Yii::$app->session->set('code', $code);
//Just use key (static string) to store in session as this session in unique per user
$phone = Yii::$app->session->get('phone');
$code = Yii::$app->session->get('code');
//Just use key that you used to store the data
我建议阅读更多关于Yii2课程的信息

请记住,您应该使用cookie在所有请求中发送会话id。此外,应用程序内开发会话很少使用,它们通常使用rest授权(如auth2和缓存)在服务器上存储数据

会话示例:假设我们有以下代码

public function actionPageCount(){
    if(Yii::$app->session->get('count'))
        Yii::$app->session->set('count',Yii::$app->session->get('count')+1);
    else
        Yii::$app->session->set('count',1);

    return Yii::$app->session->get('count');
}
用户第一次调用此操作时,if语句将为false,因为用户没有会话id,因此在else中,web应用程序将创建一个新会话,并将count设置为1。创建会话时,服务器将向浏览器或应用程序发送此标题

Set-Cookie: PHPSESSID=rl721ac6h3vfgld5repf8pcjl6; path=/; HttpOnly

这意味着创建名为PHPSESSID的新cookie,其值为rl721ac6h3vfgld5repf8pcjl6。因此,当用户再次调用该操作时。服务器将根据会话id加载会话。如果用户未包含会话id,服务器将创建新会话。从浏览器调用此方法并查看其行为,然后打开“新建专用”选项卡并再次调用,然后查看服务器是否将为您管理会话。在应用程序中,您必须保存会话id并在每个请求中添加为cookie

在移动连接中,ip可能会频繁更改,因此您可以避免在启动会话时检查ip是否相同。我无法使用数据库。那么,对于这种情况,什么是最好的选择呢?有什么建议吗?如果两个以上的用户同时使用这些应用呢?该会话可以被覆盖。否每个用户的会话不是应用程序,因此如果您有100个用户,服务器将有100个会话。但是你需要在Cookie中发送会话id。你能给我一些关于在Cookie中发送会话id的提示吗?