Powered by Looker is a neat way to share data with the world. If you’re interested in creating a proof of concept, I highly recommend checking out this post.
If you’re having issues with your embedded Looks and/or dashboards, making sure the embed URL is properly constructed is a good place to start. Creating an application to write a URL is not something we currently do, but there is some example code here.
The Steps You’ll Take
To check URL construction, I always run through these steps (more on each to later):
- Make sure the Look or dashboard exists on the “production” version of your instance
- Make sure users are authenticated with the correct permission set
- Make sure URL parameters are correctly formed
- Confirm that everything is spelled correctly
Handy Tools
To run through these checks, I find it helpful to have a couple of tools easily available:
- A URL decoder (I use this one, for no particular reason)
- A URL encoding reference (I use W3Schools, say what you will)
- Looker logs (if you have access to your instance’s logs, they can provide some helpful error messages)
Check production
If a dashboard or Look does not live on the production version of your instance (outside of developer mode), then you will not be able to get this to work. If you can’t find it, on production, make sure it’s created, saved, committed, and pushed.
Check permissions
A complete walk through of Looker’s permissioning system is outside of the scope of this post, but I highly recommend this document. It’s great. If you’re looking to limit data access, this is a great resource.
Simply put, if a user doesn’t have access and permissions to see the Look, they’ll get a 404. For example, if the embedded user doesn’t have see_lookml_dashboards
and the embeded dashboard is a LookML dashboard, we got problems.
Check URL parameters
The API call should produce an encoded URL that takes the form:
https://do.main.com/login/embed/%2Fembed%2Fitem_name_here?nonce=%22something%22&time=some_time_value&session_length=some_other_time_value&external_user_id=%22an_id%22&permissions=%5B%22permission_one%22%2C%22permission_two%22%2C%22permission_three%22...%22%2C%22permission_n-1%22%2C%22permission_n%22%5D&models=%5B%22model_one%22%2C%22model_two%22%2C%22model_three%22...%22%2C%22model_n-1%22%2C%22model_n%22%5D&access_filters=%7B%22model_one%22%3A%7B%22view_name.field_name%22%3A%22value%22%7D%2C%22model_two%22%3A%7B%22other_view_name.other_field_name%22%3A%22other_value%22%7D%7D&first_name=%22a_first_name%22&last_name=%22a_last_name%22&force_logout_login=true_or_false&signature=some_signature
We’ll go over each parameter, but the basic form is an address plus key-value pairs containing some information. Decoded, an embed URL should to look like this:
https://do.main.com/login/embed//embed/item_name_here?nonce="something"&time=some_time_value&session_length=some_other_time_value&external_user_id="an_id"&permissions=["permission_one","permission_two","permission_three"...","permission_n-1","permission_n"]&models=["model_one","model_two","model_three"...","model_n-1","model_n"]&access_filters={"model_one":{"view_name.field_name":"value"},"model_two":{"other_view_name.other_field_name":"other_value"}}&first_name="a_first_name"&last_name="a_last_name"&force_logout_login=true_or_false&signature=some_signature
The address
This should look something like https://do.main.com/login/embed/%2Fembed%2Fitem_name_here?
(not decoded)
do.main
is your Looker instance’s domain
item_name_here
is the name of your dashboard or Look. A LookML dashboard will be something likedashboards%2Fmodel_name_here%2Fdashboard_name_here
and a user-defined dashboard will be something likedashboards%2Fdashboard_number_here%20F
The parameters
nonce
is a value that identifies this request (16 character hexadecimal string). It shouldn’t be re-used (it’s a single sign-on) and should come from by a secure random number generator.
time
is a timestamp to identify when the session begins. I don’t believe it allows for decimal values, but I could be mistaken
session_length
is how long a user should be authenticated (in seconds). Pick something reasonable (no more than 30 days)
external_user_id
is Looker instance user ID of the user being authenticated
permissions
should be a grouping of Looker permissions. Something like this might workpermissions=%5b%22see_user_dashboards%22%2c%22see_lookml_dashboards%22%2c%22access_data%22%2c%22see_looks
models
is a group of models your user will have access to. Make sure they’re spelled correctly and in quotes. Something like this might workmodels=%5B%22faa%22%2C%22thelook%22%5D
access_filters
should be the group of access_filter_fields that are applied to your instance. If you don’t use them, something like this should workaccess_filters%3D%7B%22faa%22%3A%7B%7D%2C%22thelook%22%3A%7B%7D%7D
. If you use them, try thisaccess_filters={"faa":{"aircraft.tail_number":"1"},"thelook":{"users.user_id":"2"}}
a_first_name
will be the first name of your authenticated Looker user, as displayed in Looker
a_last_name
will be the last name of your authenticated Looker user, as displayed in Looker
force_logout_login
determines whether currently logged-in users will be logged out before authentication. I recommend setting this totrue
, at least for testing purposes
some_signature
will be generated by your code. It is used by Looker to verify that the secret used to sign the request is valid and that the parameters that are present in the request are identical to those that were signed when the signature was generated.
Check spelling
If anything’s spelled incorrectly, we’ll run into trouble. Typos happen (I type dimesnion
more often than I care to admit), so make sure all model names, files, etc. are spelled properly.
Other things to note
- I’ve seen certain browsers not like
%20f
and only take%20F
as an encoded/
- You may want to use an encoder reference to make sure you’ve got your
/
s,{
s, and company straight - Note a lack of spaces between decoded parameters
- I don’t believe that the string to sign should have a
https://
Version note
This was written and tested on Looker release 3.20.