Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 使用Laravel和Latcht websocket构建实时应用程序_Angularjs_Laravel_Websocket_Autobahn_Ratchet - Fatal编程技术网

Angularjs 使用Laravel和Latcht websocket构建实时应用程序

Angularjs 使用Laravel和Latcht websocket构建实时应用程序,angularjs,laravel,websocket,autobahn,ratchet,Angularjs,Laravel,Websocket,Autobahn,Ratchet,我正在构建一个封闭的应用程序(用户需要进行身份验证才能使用它)。我无法从我的Latcht会话中识别当前已验证的用户。由于apache不支持长期存在的连接,所以我将LATCHT托管在一个单独的服务器实例上。这意味着我的用户将收到两个会话id。每个连接一个。我希望能够识别两个连接的当前用户 我的客户端代码是基于AngularJS的SPA。对于客户端WS,我使用Autobahn.WS WAMP v1实现。ab框架指定了身份验证的方法:,但具体如何进行 我是否在客户端保存用户名和密码,并在执行登录后重新

我正在构建一个封闭的应用程序(用户需要进行身份验证才能使用它)。我无法从我的Latcht会话中识别当前已验证的用户。由于apache不支持长期存在的连接,所以我将LATCHT托管在一个单独的服务器实例上。这意味着我的用户将收到两个会话id。每个连接一个。我希望能够识别两个连接的当前用户

我的客户端代码是基于AngularJS的SPA。对于客户端WS,我使用Autobahn.WS WAMP v1实现。ab框架指定了身份验证的方法:,但具体如何进行

我是否在客户端保存用户名和密码,并在执行登录后重新传输这些信息(顺便说一下,这与我的SPA的其余部分是分开的)?如果是这样,这不是一个安全问题吗

服务器端将接收什么身份验证请求?我找不到任何这样的例子

请帮忙


另外,我没有足够的声誉来创建标签“Latcht”,所以我使用Ratchet(Latcht是基于此构建的)。

我可以给你一些关于WAMP-CRA的提示,这是指的身份验证机制:

WAMP-CRA不通过网络发送密码。它通过一个挑战响应方案工作。客户端和服务器有一个共享的秘密。为了对客户端进行身份验证,服务器将发送一个质询(随机的东西),客户端需要使用该密码进行签名。只有签名会被发回。客户端可能会将机密存储在浏览器本地存储中。它从未发送过


在上面的一个变体中,服务器发送的质询的签名不是在客户机内直接签名的,但是客户机可能允许从Ajax请求创建签名。当客户端已经使用其他方式(例如基于经典cookie)进行了身份验证,然后可以在正在进行身份验证的经典web应用程序中进行签名时,这非常有用。

我可以给您一些关于WAMP-CRA的提示,这是指的身份验证机制:

WAMP-CRA不通过网络发送密码。它通过一个挑战响应方案工作。客户端和服务器有一个共享的秘密。为了对客户端进行身份验证,服务器将发送一个质询(随机的东西),客户端需要使用该密码进行签名。只有签名会被发回。客户端可能会将机密存储在浏览器本地存储中。它从未发送过


在上面的一个变体中,服务器发送的质询的签名不是在客户机内直接签名的,但是客户机可能允许从Ajax请求创建签名。当客户端已经使用其他方式(例如基于经典cookie)进行了身份验证,然后可以在正在进行身份验证的经典web应用程序中进行签名时,这一点非常有用。

创建一个名为AuthenticationService的angularjs服务,在需要时注入,并使用以下方法调用它:

AuthenticationService.check('login_name', 'password');
此代码存在于名为authentication.js的文件中。它假设高速公路已经包括在内。我确实需要大量编辑这段代码,去掉其中所有多余的垃圾,它可能有一两个语法错误,但想法就在那里

angular.module(
  'top.authentication',
  ['top']
)

.factory('AuthenticationService', [ '$rootScope', function($rootScope) {
    return {
        check: function(aname, apwd) {
              console.log("here in the check function");
              $rootScope.loginInfo = { channel: aname, secret: apwd };
              var wsuri = 'wss://' + '192.168.1.11' + ':9000/';
              $rootScope.loginInfo.wsuri = wsuri;
              ab.connect(wsuri,
                  function(session) {
                      $rootScope.loginInfo.session = session;
                      console.log("connected to " + wsuri);
                      onConnect(session);
                  },
                  function(code,reason) {
                      $rootScope.loginInfo.session = null;
                      if ( code == ab.CONNECTION_UNSUPPORTED) {
                          console.log(reason);
                      } else {
                          console.log('failed');
                          $rootScope.isLoggedIn = 'false';
                      }
                  }
              );

              function onConnect(sess) {
                  console.log('onConnect');
                  var wi = $rootScope.loginInfo;
                  sess.authreq(wi.channel).then(
                    function(challenge) {
                        console.log("onConnect().then()");
                        var secret = ab.deriveKey(wi.secret,JSON.parse(challenge).authextra);
                        var signature = sess.authsign(challenge, secret);
                        sess.auth(signature).then(onAuth, ab.log);
                    },ab.log
                  );
              }

              function onAuth(permission) {
                  $rootScope.isLoggedIn = 'true';
                  console.log("authentication complete");
                  // do whatever you need when you are logged in..
              }
        }
    };
    }])
然后,您需要服务器端的代码(正如您所指出的)。我假设您的服务器端web套接字是php编码。我没办法,已经一年多没有用php编写代码了。在我的例子中,我使用python,包括autobahn gear,然后子类WampCraServerProtocol,并替换一些方法(onSessionOpen、getAuthPermissions、getAuthSecret、onAuthenticated和onClose),正如您所想象的,这些是敲门的角代码的“另一面”。我认为autobahn不支持php,因此,您必须自己对身份验证的服务器端进行编程

无论如何,我的后端工作起来更像@oberstat所描述的。我通过老式的https建立身份验证,创建会话cookie,然后执行ajax请求“票证”(这是一个临时名称/密码,我与web身份验证会话关联)。它是一次性名称/密码,必须在几秒钟内使用,否则将消失。关键是我不必保留用户的凭证,我已经有了cookie/会话,我可以创建可以使用的票据。这也有一个很好的副作用,我的ajax会话与我的web套接字会话相关,对其中任何一个会话的查询都归因于后端的同一个会话


-g

创建一个名为AuthenticationService的angularjs服务,在需要时注入,并使用以下命令调用它:

AuthenticationService.check('login_name', 'password');
此代码存在于名为authentication.js的文件中。它假设高速公路已经包括在内。我确实需要大量编辑这段代码,去掉其中所有多余的垃圾,它可能有一两个语法错误,但想法就在那里

angular.module(
  'top.authentication',
  ['top']
)

.factory('AuthenticationService', [ '$rootScope', function($rootScope) {
    return {
        check: function(aname, apwd) {
              console.log("here in the check function");
              $rootScope.loginInfo = { channel: aname, secret: apwd };
              var wsuri = 'wss://' + '192.168.1.11' + ':9000/';
              $rootScope.loginInfo.wsuri = wsuri;
              ab.connect(wsuri,
                  function(session) {
                      $rootScope.loginInfo.session = session;
                      console.log("connected to " + wsuri);
                      onConnect(session);
                  },
                  function(code,reason) {
                      $rootScope.loginInfo.session = null;
                      if ( code == ab.CONNECTION_UNSUPPORTED) {
                          console.log(reason);
                      } else {
                          console.log('failed');
                          $rootScope.isLoggedIn = 'false';
                      }
                  }
              );

              function onConnect(sess) {
                  console.log('onConnect');
                  var wi = $rootScope.loginInfo;
                  sess.authreq(wi.channel).then(
                    function(challenge) {
                        console.log("onConnect().then()");
                        var secret = ab.deriveKey(wi.secret,JSON.parse(challenge).authextra);
                        var signature = sess.authsign(challenge, secret);
                        sess.auth(signature).then(onAuth, ab.log);
                    },ab.log
                  );
              }

              function onAuth(permission) {
                  $rootScope.isLoggedIn = 'true';
                  console.log("authentication complete");
                  // do whatever you need when you are logged in..
              }
        }
    };
    }])
然后,您需要服务器端的代码(正如您所指出的)。我假设您的服务器端web套接字是php编码。我没办法,已经一年多没有用php编写代码了。在我的例子中,我使用python,包括autobahn gear,然后子类WampCraServerProtocol,并替换一些方法(onSessionOpen、getAuthPermissions、getAuthSecret、onAuthenticated和onClose),正如您所想象的,这些是敲门的角代码的“另一面”。我认为autobahn不支持php,因此,您必须自己对身份验证的服务器端进行编程

无论如何,我的后端工作起来更像@oberstat所描述的。我通过老式的https建立身份验证,创建会话cookie,然后执行ajax请求“票证”(这是一个临时名称/密码,我与web身份验证会话关联)。它是一次性名称/密码,必须在几秒钟内使用,否则将消失。关键是我不必保留用户的凭证,我已经有了cookie/会话,我可以创建可以使用的票据。这也有一个巧妙的副作用,我的ajax se
class AuthReqController extends BaseTopic {
    public function subscribe ($connection, $topic) {    }

    public function publish ($connection, $topic, $message, array $exclude, array $eligible) {    }

    public function unsubscribe ($connection, $topic) {    }

    public function call ($connection, $id, $topic, array $params) {
        switch ($topic) {
            case 'http://api.wamp.ws/procedure#authreq':
                return $this->getAuthenticationRequest($connection, $id, $topic, $params);
            case 'http://api.wamp.ws/procedure#auth':
                return $this->processAuthSignature($connection, $id, $topic, $params);
        }
    }

    /**
     * Process the authentication request
     */
    private function getAuthenticationRequest ($connection, $id, $topic, $params) {
        $auth_key = $params[0]; // A generated temporary auth key
        $tmpUser  = $this->getTempUser($auth_key); // Get the key value pair as persisted from the temporary store.
        if ($tmpUser) {
            $info = [
                'authkey'   => $tmpUser->username,
                'secret'    => $tmpUser->secret,
                'timestamp' => time()
            ];
            $connection->callResult($id, $info); 
        } else {
            $connection->callError($id, $topic, array('User not found'));
        }
        return true;
    }

    /**
     * Process the final step in the authentication
     */
    private function processAuthSignature ($connection, $id, $topic, $params) {
        // This should do something smart to validate this response.

        // The session should be ours right now. So store the Auth::user()
        $connection->user = Auth::user(); // A null object is stored.
        $connection->callResult($id, array('msg' => 'connected'));
    }

    private function getTempUser($auth_key) {
        return TempAuth::findOrFail($auth_key);
    }
}