Проверка подлинности билета qlik TargetUri не установлена - PullRequest
0 голосов
/ 13 мая 2019

Вот мой код, который я использую для проверки подлинности моего билета qlik, но когда я использую адрес обратного прокси-сервера, я не получаю TargetUri в ответе на билет. Я не совсем уверен, что я делаю неправильно. Я опубликую код, который я использую для тестирования и запроса билета на стороне сервера.

index.html - простой тестовый логин. Это отправляется на сервер на основе php, который аутентифицируется на сервере Sql. Оттуда мы кешируем учетные данные пользователя в сеансе, а затем делаем запрос CURL, чтобы получить билет.

<!DOCTYPE html>
<html>
<head>

<title>Login Test</title>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>

</head>
<body>

<form method="post">

    <input type="text" name="email" id="email" value="client@testmail.com"><br>
    <input type="text" name="pass" id="pass"  value="password"><br>

    <input type="button" value="Login" id="submit" />

</form>

<script type="text/javascript">

    $(
        function()
        {
            var email = $('#email').val();
            var pass  = $('#pass').val();

            // this is what I want to work but doesn't
            var host = 'http://rever-proxy-url';

            // this is just a hacked ip address which at the moment is the Qlik virtual proxy address which is public ally accessible at the moment, but later will be closed off to the public
            host = 'https://virtual-proxy-ip';

            var requireJsLink = host + '/prefix/resources/assets/external/requirejs/require.js';

            $('#submit').on(
                'click',
                function (e)
                {
                    e.preventDefault();

                    $.post(
                        'http://localhost:port/auth/login',
                        {
                            email: email,
                            pass: pass
                        },
                    )
                    .done(
                        function(data)
                        {
                            var data = JSON.parse(data);

                            // opens the inital requireJs file to initalize the session and authenticate
                            var url = requireJsLink + '?qlikTicket=' + data['ticket'];

                            // here when I use the Qlik virtual proxy ip then it works and I can open up the second page without the ticket appended etc. But as soon as I comment out the virtual proxy ip hack above then even though on this request i open up the require js and it loads into the browser etc with no problem on the second tab opening I get redirected back to the login page from the virtual proxy

                            var win = window.open(url, '_blank');

                            win.focus();

                            setTimeout(
                                function ()
                                {
                                    // close the require js ticket appended tab
                                    win.close();

                                    setTimeout(
                                        function ()
                                        {
                                            // open up a second window just to confirm that we are authenticated and 
                                            // can require the requireJs without the ticket appended
                                            // this is where I get redirected when not using the Qlik virtual proxy ip address
                                            var win2 = window.open(requireJsLink, '_blank');

                                            setTimeout(
                                                function ()
                                                {
                                                    win2.focus();

                                                    // close the tab for lazy dev purposes :)
                                                    setTimeout(
                                                        function ()
                                                        {
                                                            win2.close();
                                                        },
                                                        3000
                                                    );
                                                },
                                                1000
                                            );
                                        },
                                        1000
                                    );
                                },
                                1500
                            );
                        }
                    );
                }
            );
        }
    );

</script>

это код в моем php роутере, который происходит в том же ajax-запросе от запрашивающего источника. Это может быть вызов ajax, тогда мы возвращаем билет qlik. Идея заключается в том, что мы могли бы загрузить это на следующей странице загрузки с билетом или, если мобильное устройство, мы могли бы загрузить в URL в веб-окне в фоновом режиме для аутентификации сеанса и т. Д. С билетом

public static function getQlikTicket()
{
    // this is the user attributes from the successful login request that happens just before this. The user attributes get queried from the user table and stored in the session
    $user = self::getUser();

    if (empty($user['UserId']))
    {
        return false;
    }

    $selectedUser   = $user['UserId'];
    $userDirectory  = $user['UserDirectory'];
    $userAttributes = $user['Attributes'];

    $targetId = !empty($_GET['targetId']) ? $_GET['targetId'] : '';

    $xrf = getRandXrf();

    $url = "https://virtual-proxy-ip:4243/qps/prefix/ticket?xrfkey={$xrf}";

    $config = getConfigArray();

    $headers = [
        'Accept: application/json',
        'Content-Type: application/json',
        'Host: reverse-proxy-address',
        "X-Qlik-Xrfkey: {$xrf}"
    ];

    if (!file_exists($config['certificateFile']))
    {
        log('WARNING: Certificate file does not exist: ' . $config['certificateFile']);
        return false;
    }

    if (!file_exists($config['keyFile']))
    {
        log('WARNING: Key file does not exist: ' . $config['keyFile']);
        return false;
    }

    $options = [
        CURLOPT_URL            => $url,
        CURLOPT_HTTPHEADER     => $headers,
        CURLOPT_SSLCERT        => $config['certificateFile'],
        CURLOPT_SSLKEY         => $config['keyFile'],
        CURLOPT_SSLCERTPASSWD  => $config['passphrase'],
        CURLOPT_RESOLVE        => ['reverse-proxy-address'],
        CURLOPT_VERBOSE        => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_POSTFIELDS     => json_encode(
            [  
                'UserDirectory' => $userDirectory,  
                'UserId'        => $selectedUser,
                'Attributes'    => $userAttributes,
                'TargetId'      => $targetId
            ]
        ),
    ];

    $ch = curl_init();

    curl_setopt_array($ch, $options);

    $data = curl_exec($ch);

    $data = json_decode($data, true);

    log($data, 'DATA: ');

    if (!isset($data['Ticket'])) return false;

    return $data['Ticket'];
}

// router file

$router->post(
    'login',
    function ()
    {
        if (!SqlClass::doLogin($_POST['email'], $_POST['pass']))
        {
            // handle unauth response
            return;
        }

        if (!$ticket = QlikAuth::getQlikTicket())
        {
            // handle appropriate response
            return;
        }

        // handle successful response
        new Response(200, json_encode(['ticket' => $ticket]))
    }
);

вывод журнала

[ERROR][DATA: ] - array (
  'UserDirectory' => 'UserDir',
  'UserId' => 'client1@client1.com',
  'Attributes' => 
  array (
    0 => 
    array (
      'ContentAccessCode' => 'ft lkds',
    )
  ),
  'Ticket' => 'lkajdfhlajkeriu87',
  // As far as I can see this is where the problem lies. Why is this NULL?
  'TargetUri' => NULL,
)

Как указано в комментариях выше, когда я использую этот код для проверки моего имени входа в API, он работает нормально, но когда я использую адрес обратного прокси, он не работает. Самым странным является то, что все работает с обратным прокси-сервером, вплоть до требования require js с приложенным билетом. Но когда я запрашиваю вторую вкладку, меня перенаправляют обратно на страницу входа.

...