coopermaruyama/tableau-react

Trusted ticket

bthink opened this issue · 8 comments

What should be in param 'token'. What exactly is this trusted ticket?

This is not the Token from the REST API it is the ticket from the server. The following will help you:

http://onlinehelp.tableau.com/current/server/en-us/trusted_auth.htm

You have to add a trusted ip to the server and then get a ticket from the server which is what goes in the "token" param.

Ok, thanks, that was helpful!

I am using Tableau Online Server and Connected Apps to create the JWT. However, when I pass it through the react component, it returns a "Could not locate unexpired trusted ticket" error. I followed their docs here to create the JWT.

My jwt creation is cut and paste:

token = jwt.encode(
	{
		"iss": connectedAppClientId,
		"exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=5),
		"jti": str(uuid.uuid4()),
		"aud": "tableau",
		"sub": user,
		"scp": ["tableau:views:embed", "tableau:metrics:embed"]
	},
		connectedAppSecretKey,
		algorithm = "HS256",
		headers = {
		'kid': connectedAppSecretId,
		'iss': connectedAppClientId
        }
  )

I make the call to get the token and pass it to the tableau react component like this

<TableauReport url={report} token={jwt} />

This might not be an issue with this component, but I was hoping you might still be able to lend some help?

The url being created by the TableauReport component is "https://server/trusted/{jwt}/t/site/views/..."

@mcdowellalex

Hi, try changing your URL to https://server/t/site/views/...

As you can see here, the token is added to the url for you.

That error you're seeing is usually caused by using the token twice

Oh, I see - you're doing that already and saying that the URL itself after the parse is getting turned into that.

Unfortunately I no longer have an account I can test trusted tickets with, but I believe I can point you in the right direction to find out if there's potentially a bug.

The first thing you should do is try getting it working without tableau-react using just the tableau SDK and pure js.

If it works, then it is likely that there is a bug in this library. When I was first building the library I noticed that accidentally using a trusted ticket twice causes this error, so I made sure that the ticket was never re-used. It is possible that in v2 this has regressed as I only tested it against the unit tests for the trusted tickets.

If there is a bug in the library that is re-using trusted tickets you can clone this repo and then do the following to test changes to the library locally and potentially fix it and I will merge the fix:

  1. Clone this repo

  2. Build the library locally:

yarn install
yarn bundle
  1. Run the local server (in another terminal):
yarn live-server

Then go to localhost:8080/example to view the built-in demo, and try rendering your report there.

You can then make changes to src/TableauReport.jsx and it should automatically update the demo according to your changes.

I would put a breakpoint or a console.log here: https://github.com/coopermaruyama/tableau-react/blob/master/src/TableauReport.jsx#L119

If this is called then that's probably the issue.

If the component where you render the report is rendering twice that could also be the issue in which case the most likely cause is that report or url props are changing from null to not-null (if you are fetching the url or ticker asynchronously), in which case you can try something like:

{report && jwt && <TableauReport url={report} token={jwt} />}

It works without the token, the user just has to sign in a second time.

I don't believe the package is re-using any tokens. The token I create is the one that is in the url returning the 403 error.

Just to make sure I'm not going crazy with JWTs. I am creating it with python (according to the tableau connected app docs) in a rest api and returning it in the get request body. When my react site calls for it, it just stores it as is which is just a string "ajsdfkladslkalfs.kljasdjfklads". Then I pass that to the tableau-react component. This is one of the first times I have worked with JWTs but I feel I understand them fairly well. Do I have to store them in the header? Or do something different after the site gets the the token?

I cloned the repo and tried what you suggested. My report works when I don't pass a token. I just have to sign in. But when I generate a token and then pass that to the Viz component along with my reports url, I get the same error. And it does go into the invalidateToken() function on line 118.

Although, looking at the code, why would going into this function cause an issue? Doesn't that mean that the token I am passing is okay to use? Since it hasn't been previously invalidated (or used since the only way to invalidate the token is by using it). The code seems to tokenize the url and return that just fine.

So it looks like your component is running the javascript api v2 and sometime last year they moved to v3 and made some changes to how you embed.

Thankfully it is fairly straight forward with NextJS. Just have to add the script in the nextjs Script tag in the app.js. And the new embedding doesn't require us to use window or build anything, we can just pass everything to a <tableau-viz/> element.

I found the docs a bit buried here.