Skip to content

Instantly share code, notes, and snippets.

@joshvarner
Created July 11, 2012 02:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save joshvarner/1f55ab2ea3198f82cba5 to your computer and use it in GitHub Desktop.
Save joshvarner/1f55ab2ea3198f82cba5 to your computer and use it in GitHub Desktop.
Proxy for Tableau
<?php
/**
* Proxy content from a Tableau Server instance using trusted tickets
*
* @see https://www.interworks.com/blogs/jvarner/2012/07/12/proxying-tableau-server-content-using-php-and-trusted-tickets
* @see http://kb.tableausoftware.com/articles/knowledgebase/integrating-trusted-tickets-portals
*/
$server = 'tbsrv';
$username = 'jvarner';
$clientIp = (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '');
// To get a PNG
$url = 'views/foo/bar?format=png';
$contentType = 'image/png';
// To get a PDF you could use:
// $url = 'views/foo/bar?format=pdf';
// $contentType = 'application/pdf';
// Request the trusted ticket ID by sending username & client_ip via POST fields to "/trusted"
$params = compact('username');
if ($clientIp) {
$params['client_ip'] = $clientIp;
}
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => "http://{$server}/trusted",
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $params,
CURLOPT_RETURNTRANSFER => true,
));
$ticket = (int) curl_exec($ch);
curl_close($ch);
// Valid ticket IDs are positive integers
if ($ticket <= 0) {
throw new Exception("Server did not return a valid ticket.");
}
// At this point we have a valid trusted ticket ID, so let's request the content
$url = ltrim(trim($url), '/');
$fullUrl = "http://{$server}/trusted/{$ticket}/{$url}";
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $fullUrl,
// Tell cURL to follow the redirect from Tableau Server
CURLOPT_FOLLOWLOCATION => true,
// Enable cookies so that cURL handles the session ID cookie, but don't load any existing
// cookies from a file (since we don't have any)
CURLOPT_COOKIEFILE => '',
CURLOPT_FAILONERROR => true,
CURLOPT_HEADER => false,
));
// Simply output the content to the browser
header("Content-Type: {$contentType}");
curl_exec($ch);
curl_close($ch);
@colourorange
Copy link

Hi Josh,

I'm part of a team working on a Tableau email subscriptions tool. This piece of code was extremely helpful and solved our issue. So thank you! The magic line was setting CURLOPT_COOKIEFILE to ''. I originally thought there was some sort of JavaScript form submission being done and that's why we were running into issues but I guess that's not actually the case. Would you mind explaining what's happening and why this works?

Thanks!

@joshvarner
Copy link
Author

Sure, Aaron. There are actually two important options being set here: CURLOPT_COOKIEFILE and CURLOPT_FOLLOWLOCATION. CURLOPT_FOLLOWLOCATION forces cURL to follow any "Location: /foo" style redirects from the server. The CURLOPT_COOKIEFILE option ensures that cURL will respect any cookies set in the original request and pass them along if redirected, which is important if Tableau server attempts to establish a cookie-based session and then uses a redirect. Setting the cookie file option value to a blank string means that cURL won't load any cookies from a file, but will still enable cookie handling for any new cookies established for the given cURL handle-- which is what we want in this case.

I'm actually planning on writing a blog post tomorrow to more thoroughly dissect this code snippet. I'll post a link here when I finish that post.

Glad the Gist helped, Aaron!

-Josh

@joshvarner
Copy link
Author

@udara86
Copy link

udara86 commented Oct 27, 2015

Hi Josh,

This is really good, I'm not an IT expert, But I can manage many things by reading and understanding. I really not understand whether your this script will support me or not. But since you all from Tablue community, I hope you my understand my issue.

we are non profit organization who is collecting ICU bed data and healthcare data via REDCAP in order to present current issues to the government. Thereare data analysis and data visual presentation has to be done.

We purchased Tablue Server in order to do Visual presentation. But we were capable to brought only few Tablue Dashboard accessing licenses.

But we want to publish Tablue Dashboards via our WORD-PRESS website using embedded code. Instead of displaying the reports it asking authentication in the word-press embedded code.

We want user to access the reports without having individual Tablue server licences users independently. ( which cost us)

we wanted to bypass this Tablue sever authetocation popup in embedded code using Trust ticket method.

Now I think you may get my real requirement. I was searching and tested so many efforts to overcome ith this issue. Josep I think you can support me, Its enough to give guidelines. I will follow up them.

could you please let me know, Can i do my requirement using this script ?

my email: udara86@gmail.com

Bye

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment