You can configure your Web Widget to embed content from a restricted Help Center (one that requires users to sign in for access), or restricted knowledge base content (a public Help Center with articles that are restricted to specific users).
When you configure the Web Widget to include restricted content:
- Visitors to your website who are logged in can read the restricted Help Center articles via the Web Widget. Note that the customer site in which the Widget is embedded is responsible for authentication of a users email.
- Visitors who are not logged in, however, see only public articles. If there are no public articles, the Help Center features do not appear in the Web Widget.
This article includes the following topics:
For more information on the Web Widget, see Using Web Widget to embed customer service in your website.
For information on restricted Help Centers and knowledge base content, see Restricting your content to logged in users only and Restricting access to knowledge base content.
Determining your Help Center security settings
The Web Widget allows you to display content from a Help Center with any of the following security configurations. You may need to enable or disable the Require sign in option in your Help Center security settings, in Guide, based on your type of Help Center.
Type of Help Center | Enable "Require sign in"? |
---|---|
A public Help Center, where all content is available to the public. | Don't enable Require sign in. |
A restricted Help Center, where users must be registered and signed in to view any content. | Enable Require sign in. |
A public Help Center with restricted content, where some articles are only available to specific users, and others are available to all Help Center visitors. | Don't enable Require sign in. Everyone can see the unrestricted articles in your Help Center without logging in. However, only signed-in users with the correct permissions can see the restricted articles. |
To check your Help Center security settings
- In Guide, click the Settings icon (
) in the sidebar.
- In the Security section, enable or disable the Require sign in option, if needed, based on your type of Help Center.
- If you have a restricted Help Center or a public Help Center with restricted content, proceed to Setting up the Web Widget to show restricted content.
Setting up the Web Widget to show restricted content
If you have a restricted Help Center or a public Help Center with restricted content that means you have restricted articles (see Determining your Help Center security settings). If you want restricted articles to appear in the Web Widget, you need to configure your Web Widget settings and add additional snippets to your website's code.
If you have a public Help Center, this task doesn't apply to you.
To get started, you need to check your Widget settings and generate a shared secret.
To check your settings and generate a shared secret
- In Support, click the Admin icon (
) in the sidebar, then select Channels > Widget.
- Click the Customization tab.
- Make sure that the Help Center toggle is turned on.
If you haven't already, go to your Guide settings and enable or disable the Require sign in option, based on your type of Help Center (see Determining your Help Center security settings).
- Scroll to Security Settings, and click Configure.
- In the Allowlist box, enter the subdomains that contain the Web Widget. This allows restricted Help Center content to display in the widget for authenticated users.
For your security, we recommend adding subdomains to the allowlist. If you have specific reasons why restricting access to particular subdomains will not work, you may leave this box empty.
- Select Allow agents to access restricted Help Center content to allow restricted Help Center content to appear when agents and admins access the Web Widget.
If you have a restricted Help Center and agent access is not enabled, the Help Center features will not display in the Web Widget for agents and admins. If you have restricted articles and agent access is not enabled, agents will only encounter the public content.
- Configure Shared Secret:
- Create a shared secret by clicking the Generate button:
Because it is a security setting, your shared secret is intended to be generated, copied and pasted into a communication with your engineering team or directly into your codebase in one sitting. It is not to be entered into a browser.
Note: The shared secret is intended to remain secure. As a result, it will only appear in full one time. If you don’t have access to the shared secret and need the full secret to create your token, you can reset the secret by clicking Reset. - If you believe that your shared secret has been compromised, after you reset your shared secret you can revoke all tokens. This will invalidate the access of anyone that had authenticated previously and will not allow restricted content to be viewed until a new valid token has been issued.
- Create a shared secret by clicking the Generate button:
Once you have generated the shared secret, use it to create a JWT token (Learn more about JWT) that you'll add to your Web Widget snippet.
To create a JWT token and add the code to the Web Widget snippet
- Construct a server-side payload of data for the JWT token. This needs to have the following information:
- name: Customer's name
- email: Customer's email
-
iat: Integer value of the current timestamp, in seconds. Some functions in specific languages i.e. JavaScript's Date.now() return milliseconds, so please make sure you convert to seconds.
Iat for Web Widget authentication permits up to two minutes clock skew.
- jti: Unique identifier for this token. Cannot be the same as any other jwt tokens already sent through. A random 64 bit number for example.
- Use the code samples below to find a template that fits your language needs.
- Add a function which fetches your JWT from your server, and makes a callback with the JWT value. Replace "YOUR_JWT_TOKEN" with the token you created. Make sure to put this code before the Web Widget snippet:
<script type="text/javascript"> window.zESettings = { webWidget: { authenticate: { jwtFn: function(callback) { callback('YOUR_JWT_TOKEN'); } } } }; </script>
Tokens expire after two hours. You can remove them from local storage sooner by adding the following API call when the user is logging out:
<script type="text/javascript"> zE(function() { zE.logout(); }); </script>
Code samples
Your token needs to be dynamically generated from the server-side on page load. Find the template below that fits your language needs. Customize the sample as needed, making sure to replace the #{details} with your own information.
If none of these samples match your needs, JWT has a more extensive list of JWT libraries to explore.
Ruby
First, install ruby-jwt.
If you're using Rubygems:
gem install jwt
If you're using Bundler, add the following to your gem file:
gem 'jwt'
Next, generate a token using the shared secret:
require 'jwt'
payload = {
:name => "#{customerName}",
:email => "#{customerEmail}",
:iat => timestamp,
:jti => "#{uniqueId}"
}
token = JWT.encode payload, "#{yourSecret}"
NodeJS
Install jsonwebtoken:
npm install jsonwebtoken --save-dev
Then, generate a token using the shared secret:
var jwt = require('jsonwebtoken');
var payload = {
name: '#{customerName}',
email: '#{customerEmail}',
iat: #{timestamp},
jti: '#{uniqueId}'
};
var token = jwt.sign(payload, '#{yourSecret}');
Python
Install python-jose:
pip install python-jose
Generate a token using the shared secret:
from jose import jwt
var payload = {
'name': '#{customerName}',
'email': '#{customerEmail}',
'iat': #{timestamp},
'jti': '#{uniqueId}'
}
token = jwt.encode(payload, '#{yourSecret}'
PHP
Download PHP-JWT:
composer require firebase/php-jwt
Generate a token using the shared secret:
use \Firebase\JWT\JWT;
$payload = {
'name' => '#{customerName}' ,
'email' => '#{customerEmail}',
'iat' => #{timestamp},
'jti' => '#{uniqueId}'
};
$token = JWT::encode($payload, '#{yourSecret}');
Elixir
Add `json_web_token_ex` to your `mix.exs` file:
defp deps do
[{:json_web_token, "~> 0.2"}]
end
Generate a token using the shared secret:
data = %{
name: "#{customerName}",
email: "#{customerEmail}",
iat: "#{timestamp}",
jti: "#{uniqueId}"
}
options = %{ key: "#{yourSecret}" }
jwt = JsonWebToken.sign data, options
45 Comments
This is amazing! Extremely helpful!!!
This is very helpful. Thanks!!
However, we have a couple of questions and it would be great to get some clarity. We have a restricted Help Center (requires sign-in) and have followed all of the above instructions. The help content shows up in the web widget window in our platform. However, when we click on "view original content" button, it opens a new page and still asks the user to sign-in.
1. Are we missing something? Wasn't the updated widget with the shared secret snippet supposed to take care of this by authenticating the user from web widget, to see the content online?
2. Will "Whitelisted Domains" setting help? We tried but it seemed not to.
(apologies for the novice questions but what we are trying to do is not have a public Help Center but have our platform users access the help center from within the system via web widget)
Hi - any help regarding above comment? Thanks!
Hey Atif,
I'm going to move this into a ticket for you since we have to go through some account specific info with you to troubleshoot. I'll see you in the ticket shortly!
Hello,
I have this implemented nicely on our companies platform however I seem to have an issue. I am working on re-authenticating a user on our platform while they stay logged in but your widget seems to not support this? The advice for removing the restricted article access authentication is to call zE.logout() but there is not the relevent zE.login() function to enable access. I am wondering if it is intended to only reset the window.zESettings with a new JWT token to reauthenticate? Note that this is only for a repeat authentication and not the initial one while also not logging out of our platform.
Thank you.
Michael: I see you have a ticket for this so I'll reach out there for some additional details on what you are seeing.
Hi Erica, I am working on the same functionality as Michael, what was the final answer?
@Edgar, please contact support@zendesk.com and our advocacy team should be able to assist you. Thanks!
I have the following piece of code which works perfectly in Chrome but not IE 11:
<script type="text/javaScript">window.zESettings = {webWidget: {authenticate: {jwt: <?php echo json_encode($wsstoken); ?>}, helpCenter: {suppress: false, filter: {category: '200322819-Practice'}}}};</script>
I have a valid $wsstoken, and the category '200322819-Practice' has restricted access hence the JWT required. The behaviour in IE as if the JWT authentication does not work. FYI I have also tested the filter of a category which does not have restricted access and that worked as expected.
Do you have any suggestion on how to get this to work in IE 11?
server:
browser:
browser result:
why?
About this jwt, i can login about this https://support.zendesk.com/hc/en-us/articles/203663816-Setting-up-single-sign-on-with-JWT-JSON-Web-Token-
Hi 黄明就,
My name is Garrick - I'm a member of our Tier 3 Support Architect team and I'm here to help! Since this appears to be an issue with your specific implementation, I'm going to reach out to you via a Ticket for us to troubleshoot the issue. I'll be in touch shortly.
We seem to have the same problem as 黄明就. I always get could not be verified. Can this token be the same JWT token as we generate for the Guide authentication?
Hi Vahid!
The JWT token would need to be different compared to the one used to authenticate against Guide via the SSO integration. I hope this helps!
Hi Alexander,
So we do generate a different token each time for SSO and for the guide, what I meant was that it is the same algorithm and the same parameters. We are using the same algorithm and get Could not be verified. Is there anyway to debug this?
Actually I realized that the shared secret was different between the SSO token and the web widget token. You must use the appropriate shared secret for each.
We show help center content in the web widget, but the images are not shown if the user is not logged in the zendesk site (we have SSO configured).
If end-user clicks on "view original article" then SSO happens, the user is logged in and from that moment on, all images part of help content are correctly displayed.
What is the correct way to SSO authenticate the user with help center so that images are correctly displayed IN the widget?
Thanks!
Hi Javier! Welcome to the Community!
I'm going to check on this for you, because I'm not totally sure of the answer. Stand by!
Hi Javier!
Please send an email to support@zendesk.com with more details about your scenario, as we will need to investigate your account to understand better the desired outcome. Thank you!
just did... thanks!
Hello,
I am trying to configure a web widget for a restricted help center. Ideally I need to be able to test the web widget while running my application from localhost. I added localhost to this list of whitelisted domains, but while running the application from localhost I only see the contact form and not the articles from the help center. However, when running the application from our dev url that is also whitelisted I get the articles to appear. Any help would be appreciated.
I want the widget to be loaded on demand, not just everytime the user enters the page.
There are two cents:
- Trying to load the script with $.getScript (for example) throws
Error: Key is missing from snippet
at new e (asset_composer.fb4a55c4f794453a91d7.js:1)
at asset_composer.fb4a55c4f794453a91d7.js:1
at f (asset_composer.fb4a55c4f794453a91d7.js:1)
Solution: Dont forget to set the ID of the inserted script Tag ("ze-snippet")
There's something in here that may be confusing people.
The shared secret generated at Settings -> Widget -> Security Settings -> Configure looks like a hexadecimal number but it isn't. It's just a regular string that should be parsed into bytes as UTF-8 before being passed to the SHA256 algorithm.
The fact that it only uses hexadecimal characters makes it look like it should be parsed as a hexadecimal number. I spent a day doing that and getting the "* Could not be verified" 400 error before figuring out what the issue was. The documentation above really should clarify this.
We have "anybody can submit tickets" disabled in our Support->Customers settings, which means people need to login in order to submit a ticket. Can we use this Shared Secret + JWT option to allow ticket submission from the Web Widget? We had to disable this feature in our widget because it did not work with our closed Zendesk.
Hi Debbie,
I reached out to our team internally and it looks like authenticated ticket submission is not yet supported but it's on the roadmap. That being said, it may be possible to still set this up, however, unauthenticated users would still see the contact form within the widget. They just wouldn't be able to actually submit the ticket unless they were authenticated.
Hope this information helps!
Is it possible to use a wildcard for the subdomain? for example a typical SaaS (including zendesk) might use client-subdomain.product.com, so id like to whitelist *.product.com?
Hello Mathew,
This is something that isn't within the capabilities of the base program. I've gone ahead and linked an article below that going into further detail on renaming you subdomain in case you have any other question on the topic.
Renaming Your Subdomain
What are the values of the customer username and customer email used for?
Hello Daan,
The user name is generally the email of the customer. Let us know if there is anything else we can clarify for you.
Best regards!
Thanks Devan, but is that used for anything, like authentication/matching to the users in Zendesk?
Hello Daan,
Yes is it used for authentication and will be what ties them to any tickets created for them or by them.
Please sign in to leave a comment.