1. Create a JSON object of a user’s information
The first step is to take your user information that you want sent over to UserVoice and put into a JSON object.
||String||yes||-||A unique identifier for the user (ex: the user_id in your system).|
||Timestamp||‘yes’ when using Java SDK||never||Expiry time of the token in format YYYY-MM-DD HH:MM:SS and is in GMT. Defaults to never expiring.|
|String||yes||-||The email address used for notification emails.|
||String||anonymous||If not set the user will be shown as ‘anonymous’.|
||String||The account’s or forum’s default locale||ar, bg, cn, cz, da, de, en, es, et, fi, fr, fr-CA, he, hr, it, ja, lv, nl, no_NB, pl, pt, pt_BR, ro, ru, sk, sl, sr, sr-Latn, sv-SE, tr, zh-TW||Set this users locale (language).|
||Boolean||false||true, false||Defaults to false. True indicates that the email you’re using is trusted, which lets you SSO into admin users and revoke adminship of users. trusted=false can’t log you into an admin unless you pass admin:accept|
||String||-||accept, deny||Make this user an owner of your UserVoice account giving them access to adding admins, changing plans and billing info.|
||String||-||accept, deny||Grant the user account admin access. NOTE: admin:deny requires trusted:true. Passing admin:deny will remove Contributor sidebar access.|
||Array||-||Exclusive list of Forum ids user has access to (doesn’t restrict admins).|
||Array||-||List of Forum ids user does not have access to (doesn’t restrict admins).|
||URL||-||Sets all user profile links to this URL. Only set if you don’t want people to see each other’s UserVoice profiles and use your own URL.|
||URL||[Gravatar URL]||Dimensions are 50px by 50px. If left blank an avatar will be pulled from Gravatar|
||Boolean||true||Whether the user will receive updates on suggestions (on create only)|
||Boolean||false||Whether the user will receive updates on suggestion comments (on create only)|
You should end up with something that looks like this (for .NET see the example code):
2. Create a Single Sign-On Token
Next, we’ll turn that JSON object into a token that grants the user access to UserVoice.
- Encrypt the JSON object with AES using your
uservoice_subdomain(If you’re acme.uservoice.com then this value would be ‘acme’) as the password and your
sso_keyas the salt to generate an SSO token. You can get your
sso_keyfrom the ‘User Authentication’ portion of General Settings.
- Base64 encode the encrypted output to generate the token.
- Escape the token to make it web-safe.
- If you are using multibyte strings in PHP, use mb_internal_encoding(‘ASCII’); & mb_internal_encoding(
); around the SSO generation code
We’ve created code snippets for most major languages. Remember to set your
sso_key (both case sensitive) in them.
- java (‘expires’ field required)
- python (v2.x)
- Force.com (Apex class) (test class required to deploy the code to a production environment)
Alternatively, all our SDKs include the SSO token generation code (in addition to our API clients). Find links to the SDKs here.
3. Passing the Single Sign-On Token to UserVoice
The next step is to forward the token on to UserVoice by including it as a URL parameter named
sso. You have a couple options in how you do this:
- You can append the token onto a link to your UserVoice forum (ex:
You can create a link to
https://yourdomain.com/feedbackand then have that URL generate a token and redirect to
If you’re using our Feedback Tab widget you can include the SSO token in the widget configuration (this is required if you want to have your feedback tab work on a private forum with SSO).
The latter method is recommended and all you need to do is add the below line to your widget embed code:
So the complete embed code might look something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
4. Login Redirection
What we’ve described so far allows you to allow take a user who’s logged into your system and send them to your UserVoice forum. But, what if they go directly to your UserVoice forum before logging into your system? You can handle this by setting a remote login URL where your users will be sent when they arrive at UserVoice not logged in.
Let’s say your customer portal (acme.uservoice.com) is set up to only allow SSO users and your default forum (
https://acme.uservoice.com/forums/123-general-feedback) is publicly accessible.
- Go to the “Site” tab of Settings and add your SSO Remote Sign-in URL,
- A user goes to acme.uservoice.com
- They can browse the forum but when they go to vote (or, if the forum is private) then they’re prompted to sign in.
- User clicks the sign-in button and is forwarded to
- We store the page that the user was on in a session cookie on our server.
- Either your users will be redirected to your site or your login page will appear in a popup window. This is not something that can be controlled. If your site content is private (e.g. the user is trying to get to a private Forum), then he/she will be redirected to a full login window. If the content is public (e.g. the user is logging in from the widget or a public Forum) then the login window will appear as a pop-up. The uv_size parameter will either be ‘window’ when it’s a redirect and ‘popup’ when your login is inside a popup window.
- User logs in to your Login page and signs in.
- Your system then forwards them back to the page they came from.
- You construct the return URL based on the ‘return’ value that we provided in step 3, and then add the SSO token (e.g. https://acme.uservoice.com/login_success?sso=XXXXXXXXX)
- PHP example code that does this: header(‘Location: https://acme.uservoice.com/login_success?sso=XXXXXXXXX’)
- Ruby on Rails example code that does this: redirect_to “https://acme.uservoice.com/login_success?sso=XXXXXXXXX”
- If the user is directed back to UserVoice but still in a pop-up window, then likely you are not being consistent with your use of HTTP and HTTPS - if the URL of your customer portal is HTTP, then the redirect must be as well (and likewise with HTTPS).
This would work the exact same way if the forum was private. The only difference would be that after step 2 the user would be immediately sent do
https://acme.com/login?return=%2Flogin_success&uv_login=1 to gain access to the forum.
5. Logging Out (optional)
There are two scenarios you want to cover. When an SSO user logs out of your system and when an SSO user logs out from UserVoice.
Logging out of your site from UserVoice
By default, if a user logs out from UserVoice they are simply logged out from UserVoice. Because of the seamless nature of the SSO system from your site to UserVoice user’s may believe logging them out of UserVoice would log them out of your system. This is especially important if your users are often on public computers. Fortunately there’s an easy way to log users out of your system when they log out of UserVoice.
Go to the “Site” tab of Settings and enter your logout url (ex:
https://acme.com/logout) in as the SSO Remote Sign-out URL. Once that’s set any time a user logs out they’ll be forwarded to the URL you’ve entered.
Logging out of UserVoice from your site
If you’d like to make sure your users are logged out of UserVoice when they sign out of your service (especially if your users are often using public, shared computers) drop the following
<script> tag onto the page after sign out:
6. Granting Permissions
Access to Forums
If you have a private forum there are two ways to give an SSO user access:
- Add the
allow_forumsparameter to your JSON object with an array of UserVoice Forum IDs you want that user to be able to access. You can find the IDs in the URLs of your forum. For example for
https://acme.uservoice.com/forums/3-general-feedbackthe Forum ID is ‘3’.
- Don’t add the
allow_forumsto your JSON and just make sure that all your private forums have the ‘Authorize all Single Sign-On (SSO) users’ box checked.
You can also use the
deny_forums to do the inverse: grant everyone access with the ‘Authorize all Single Sign-On (SSO) users’ option but then just deny specific users from some forums.
Granting Admin Privileges
By adding the
admin parameters to your JSON object you can add (‘accept’) or remove (‘deny’) these privileges from an SSO user:
A couple important things to note:
- For each admin who would like to sign in via SSO, you must do one of the following: (1) add “admin”:”accept” to the JSON object; or (2) if this user is already an admin of your account with a standard username and password, add “trusted”:”true” to the JSON object, thus indicating that you trust the identity of the person using the email address.
- In order to revoke admin rights, pass trusted:true AND admin:deny. You cannot revoke admin rights without a trusted token.
- You can have as many owners/admins as your plan allows.
- An owner is automatically an admin.
- You can have multiple owners.
- If you add owners/admins and are on a per admin plan then this will increase the monthly cost of your subscription and may incur some immediate pro-rated upgrade charges.
7. Error Logging
Every Single Sign-On Token that’s passed to UserVoice is logged along with whether the token was accepted or not. We’ve made this log available to you via our debug console (this can also be accessed by going to Settings -> Logs in your Admin Console). Please check there for any errors.
8. Common Issues
- If the token is consistently expiring, the ‘expires’ parameter in the JSON object may not be in the correct syntax, or in the correct timezone (this should be in UTC/GMT). Also note that the expiration date/time must be in the future.
- If the user is redirected to your website login in a pop-up window, and then is directed back to UserVoice after sign-on but still in a pop-up window, then the URLs in your code might be mismatched. Please make sure to use HTTP and HTTPS consistently, and, if you are using a domain alias, to make sure that the URLs are the same throughout (i.e. don’t use both a CNAME and standard UserVoice address)
If you have any questions please contact firstname.lastname@example.org.
- Please include your code and a log output (including all the warnings PHP interpreter prints).
- Print the original user data in JSON, the encrypted data, the URL-escaped data, and finally how you are using it (the entire URL which you are using).