Menu

SSO - Automatically Sign in From Your Own Website

This article will explain how to use Thinkific's SSO (Single Sign On) feature to sign into your Thinkific school from your website.

SSO, or Single Sign On, is a feature that allows a user to sign into an external website and a Thinkific school in one action. A demonstration of this feature is available here.


Note: This is a premier plan feature that should only be implemented by those with access to software development resources. If you are not familiar with SSO, it is likely not required for your situation


How Thinkific's SSO Works


The way it works is that a users signs into your external site. Once they have been authenticated, your application will construct a token (JWT) and redirect to Thinkific’s SSO URL with this token as a query string parameter. Thinkific deconstructs this payload and either finds the user and signs them in, or if they don’t already have an account on your Thinkific site, creates an account and signs them in.


The JWT Payload


Your application must construct the JWT payload and sign it using your Thinkific API key.  The key can be found under the API section of your Thinkific admin dashboard, under your Advanced Settings. The best practice for security is to generate the JWT token on a server and then retrieve it from the client side, rather than exposing the JWT shared secret in the client-side JavaScript.

Note: Do not base 64 encode your API key when signing your JWT token. Our application expects the API key as-is when verifying your JWT token.

The JWT payload is typically constructed as a hash. The following attributes are supported:


[{
    "first_name": "Thinkific",
    "last_name": "Admin",
    "email": "thinkific@thinkific.com",
    "external_id": "thinkific@thinkific.com",
    "bio": "Mostly harmless",
    "company": "Thinkific",
    "timezone": "America/Los_Angeles",
    "iat": 1520875725
}]


  • email - the email of the authenticated user. This is REQUIRED. If external_id is not supplied, email will be used as the unique identifier.
  • first_name - the first name of the authenticated user. This is REQUIRED.
  • last_name - the last name of the authenticated user. This is REQUIRED.
  • external_id - an identifier for the authenticated user. This is typically the id of the user in your system. This is OPTIONAL, but if supplied will be used as the unique identifier of the user. What this means is that when your student is trying to log in and you have included external_id in the payload, the Thinkific database will look for a user with that external_id. If that user is not found, the system will attempt to create them. 
  • bio - a textual bio of the user. This is OPTIONAL.
  • company - the user's company. This is OPTIONAL.
  • timezone - the user's timezone abbreviation (as defined here: https://www.iana.org/time-zones). This is OPTIONAL.
  • iat - must be the number of seconds since UNIX epoch. This is essentially the time that the JWT payload was issued. This is REQUIRED.


There are various libraries for working with JWT. A list can be found here. We recommend using the HS256 algorithm.

One thing to be aware of is that the JWT payload is merely encoded and signed, not encrypted, so don't put any sensitive data in the hash table. JWT works by serializing the JSON that is being transmitted to a string. It then base 64 encodes that string and then makes an HMAC of the base 64 string which depends on the shared secret. This produces a signature that the recipient side can use to validate the user.


The return_to parameter

After a user is authenticated in your system, it should redirect to your Thinkific school's SSO URL. As part of the redirect URL, you can append a return_to query string parameter that is an encoded URL that the user will be returned to after the sign in to your Thinkific school is complete. For example:

https://{your-school}.thinkific.com/api/sso/v2/sso/jwt?jwt={payload}&return_to=https%3A%2F%2Fyoursite.com


The error_url parameter

When attempting to use the SSO, errors can occur. For example, the user's email address may be improperly formatted. In these cases, you may want the user to be redirected to an error page of your choosing. For example:

https://{your-school}.thinkific.com/api/sso/v2/sso/jwt?jwt={payload}&return_to=https%3A%2F%2Fyoursite.com&error_url=https%3A%2F%2Fyoursite.com/sso_error


The Thinkific SSO URL

The Thinkific SSO URL is the URL on your Thinkific school that you redirect to after a user has successfully authenticated in your system. It has the following structure:

https://{your-school}.thinkific.com/api/sso/v2/sso/jwt?jwt={payload}&return_to={url to return to}&error_url={url to redirect to in the case of an error} 

  • The jwt parameter is the JWT payload that you construct and is REQUIRED. 
  • The return_to is the url that you want the user to be redirected to after signing in to your Thinkific school. It is OPTIONAL. 
  • The error_url is the url that you want the user to be redirected to in the case of an error. This is OPTIONAL. 
  • If the return_to url is not supplied, the user will be redirected to their default page within your Thinkific school. 
  • If the error_url is not supplied, the user will be redirected to the return_to url that you supplied OR, if no return_url is supplied, to a generic Thinkific error page.


Ruby Example

 

# Assuming that you've set your API key and Thinkific subdomain in the environment, you
# can use the Thinkific SSO from your controller like this example.
require 'securerandom' unless defined?(SecureRandom)
class SessionController < ApplicationController
  # Configuration
  THINKIFIC_API_KEY = ENV["THINKIFIC_API_KEY"]
  THINKIFIC_SUBDOMAIN = ENV["THINKIFIC_SUBDOMAIN"]
  def create
    if user = User.authenticate(params[:login], params[:password])
      # If the submitted credentials pass, then log user into Thinkific
      sign_into_thinkific(user)
    else
      render :new, :notice => "Invalid credentials"
    end
  end
  private
  def sign_into_thinkific(user)
    # This is the meat of the business, set up the parameters you wish
    # to forward to THinkific. All parameters are documented in this page.
    iat = Time.now.to_i 
    payload = JWT.encode({
      :iat   => iat, 
      :first_name  => user.first_name,
      :last_name => user.last_name,
      :email => user.email,
     }, THINKIFIC_API_KEY)
    redirect_to thinkific_sso_url(payload)
  end
  def thinkific_sso_url(payload)
    url = "http://#{THINKIFIC_SUBDOMAIN}.thinkific.com/api/sso/v2/sso/jwt?jwt=#{payload}"
    url += "&amp;return_to=#{URI.escape(params["return_to"])}" if params["return_to"].present?
    url += "&amp;error_url=#{URI.escape(params["error_url"])}" if params["error_url"].present?
    url
  end
end


Error Handling

 If an error occurs, the user will not be signed into your Thinkific school. There are several cases when this might occur:

  1. Your code does not provide the JWT payload 
  2. Your JWT payload is not correctly signed 
  3. Your JWT payload is expired - this is based on the age of the IAT parameter. Thinkific allows a 2 minute leeway of accuracy to account for things like clock skew. 
  4. A validation error occurs when creating a new user in your Thinkific school (if one of the required parameters is missing, for example). 
  5. Some other unforeseen exception occurs.


If an error does occur, and you have provided a return_to parameter, Thinkific's SSO will not sign the user in and will redirect to the supplied return_to URL with 2 parameters:


  • kind - the type of error (currently one of 6 possibilities: jwt, validation, expired_token, invalid_iat and unspecified) 
  • message - the error message


If an error does occur, and you have provided an error_url parameter, Thinkific's SSO will not sign the user in and will redirect to the supplied error_url with the same parameters as above.


  • The error_url is used preferentially to the return_to url if both are provided


If an error occurs and you have not provided a return_to parameter, Thinkific's SSO will not sign the user in and will display the error message on the default page of your Thinkific school.


Customizing your Site Theme

Often when using SSO, you'll want to keep your student users from signing up in the traditional manner.


There are three steps we recommend to customize your Thinkific site theme. You can read more about customizing here.


1. Catch-all redirect in your theme's meta_tags to redirect your students from the Thinkific Sign In or Sign Up pages to your external site.

    example: <script>window.location.href = 'https://www.yoursite.com';</script>

2. Redirect the "Sign In" link in your header to your external site.

3. Redirect the "Buy" button for users who are not signed in to your external site.


As this code will vary widely across themes and external sites, we can't give specific instructions. If you have any questions, please reach out! 

Did you find it helpful? Yes No

Send feedback
Sorry we couldn't be helpful. Help us improve this article with your feedback.