How to set up Laravel 5.2 to connect to API

与世无争的帅哥 提交于 2020-01-17 06:08:22

问题


I have a backend C++ application that receives JSON requests using a standard TCP connection. This application manages all the business logic (user authentication, transaction processing, data requests and validation).

How do I need to setup Laravel 5.2 to connect to this server for user authentication and also transaction processing? I do not need any database on the Laravel side as all the data will be accessed through the C++ application.

As a bonus, I would also like to incorporate JWT for the user authentication part if that will be possible.

The code below is the way I currently connect to the application server using standard PHP. I want the same functionality but in a more Laravel way.

class tcp_client
{
    private $sock;

    function __construct()
    {
        // create the socket
        $this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if (!is_resource($this->sock))
        {
            // throw exception
        }

        // set socket options
        $this->set_options();
    }

    function connect($host, $port)
    {
        $timeout = 3;
        $startTime = time();
        while (!socket_connect($this->sock, $host, $port))
        {
            if ((time() - $startTime ) >= $timeout)
            {
                // throw exception
            }
            sleep(1);
        }
    }

    private function set_options()
    {
        if (!socket_set_option($this->sock, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 5,
                    'usec' => 0)))
        {
            // throw exception
        }

        if (!socket_set_option($this->sock, SOL_SOCKET, SO_SNDTIMEO, array('sec' => 5,
                    'usec' => 0)))
        {
            // throw exception
        }
    }

    public function request($request)
    {
        // the first 6 characters will indicate the length of the JSON string
        $request = str_pad(strlen($request), 6, '0', STR_PAD_LEFT) . $request;

        //Send the message to the server
        if (!socket_send($this->sock, $request, strlen($request), 0))
        {
            // throw exception
        }

        //Now receive header from server
        $header = 0;
        if (socket_recv($this->sock, $header, 6, MSG_WAITALL) === FALSE)
        {
            // throw exception
        }  

        //Now receive body from server
        $body = "";
        if (socket_recv($this->sock, $body, $header, MSG_WAITALL) === FALSE)
        {
            // throw exception
        }

        return $body;
    }

}

回答1:


I have managed to sort this out on my own by mimicking the DatabaseUserProvider.

  1. Create folder App\Blah with sub folders App\Blah\Auth and App\Blah\TCP

  2. Create a new user provider

    > php artisan make:provider App\Blah\Auth\BlahUserProvider
    
  3. Copied the contents of \vendor\laravel\framework\src\Illuminate\Auth\DatabaseUserProvider.php to the new provider (BlahUserProvider.php) and changed the class name back to BlahUserProvider.

  4. Created App\Blah\TCP\TCPClient.php and copied the contents of the class in my question to this file.

  5. Change the namespace and use the TCPClient and stdClass in BlahUserProvider.php

    namespace App\Blah\Auth;
    use App\Blah\TCP\TCPClient;
    use stdClass;
    
  6. Replaced the contents of function retrieveByCredentials in BlahUserProvider with

    public function retrieveByCredentials(array $credentials)
    { 
      $tcp_request = "{\"request\":\"login\","
                   . "\"email\":\"" . $credentials['email'] . "\","
                   . "\"password\":\"" . $credentials['password'] . "\"}";
    
      $tcp_result = json_decode(str_replace("\n","\\n",$this->conn->request($tcp_request)), true);
    
      $user = new stdClass();
      $user->id = $tcp_result['user']['id'];
      $user->name = $tcp_result['user']['name'];
    
      return $this->getGenericUser($user);
    }
    
  7. I also replaced function retrieveById with the same contents as function retrieveByCredentials for now just so the user can log in because I still have to create the request in the C++ application.

  8. Extended the createUserProvider function in \vendor\laravel\framework\src\Illuminate\Auth\CreatesUserProviders.php to include my new driver and also added function createBlahProvider

    public function createUserProvider($provider)
    {
      $config = $this->app['config']['auth.providers.' . $provider];
    
      if (isset($this->customProviderCreators[$config['driver']]))
      {
        return call_user_func(
                $this->customProviderCreators[$config['driver']], $this->app, $config
        );
      }
    
      switch ($config['driver'])
      {
        case 'database':
            return $this->createDatabaseProvider($config);
        case 'eloquent':
            return $this->createEloquentProvider($config);
        case 'blah':
            return $this->createBlahProvider($config);
        default:
            throw new InvalidArgumentException("Authentication user provider [{$config['driver']}] is not defined.");
      }
    }
    
    protected function createBlahProvider($config)
    {
      $connection = new \App\Blah\TCP\TCPClient();
      return new \App\Blah\Auth\BlahUserProvider($connection, $this->app['hash'], $config['model']);
    }
    
  9. Changed the provider in config\auth.php to the blah user provider

    'providers' => [
      'users' => [
        'driver' => 'blah',
        'model' => App\User::class,
    ],
    


来源:https://stackoverflow.com/questions/38181470/how-to-set-up-laravel-5-2-to-connect-to-api

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!