Skip to main content
Setting up Instant Auth (Academies)

Customer Learning Cloud: Generate URLs to automatically log your user into your Academy

Support avatar
Written by Support
Updated over 3 weeks ago

Instant Auth is designed for customers who want something more integrated than email+password authentication (you don’t want your learners to have to manage a separate password for your Academy) but do not have an IDP (Identity Provider) to use for SSO.

Instant Auth has only one requirement: You have a server which you control, where your users are able to sign in already.

With Instant Auth, you can give your server the ability to on-demand generate a URL which will automatically cause your learner to become logged into your Academy, regardless of whether the account even exists yet.

How Instant Auth Works

How to Implement Instant Auth

Prerequisites:

  1. You have access to the Workramp API and have an API Token

  2. You have a server where users can log in.

API Reference:

Sample code

Here’s code to make a login URL for a user, assuming their details are:

Replace the placeholders your_academy_id_here, your_api_token_here, and your_secret_key_here with your own values.

  • To generate an API token, please follow the steps in our help article. Check out this help article if you are just getting started using our API.

  • Your academy ID is shown in the URL when you go in to edit your academy as an admin from the Theming page:

  • Your secret key is available in your academy admin under Settings → Registration after you “Enable Instant Auth.”

We’ve prepared some sample code for you in several languages to get you started:

  • Python

  • Node.js

  • Kotlin

  • Ruby

  • C#

Python

This is using the most popular JWT library: PyJWT.

# First, install dependencies like this:
#
# pip install PyJWT requests

import jwt
import requests
import json
from datetime import datetime, timedelta

workramp_api_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' # 40 characters
ia_secret_key = '....' # 128 characters, from Settings->Registration
your_academy_id = '' # A GUID, from URL when you are in Academy settings

raw_jwt = {
'name': 'Jane Doe',
'sub': 'instant_auth_test@example.com',
#'dest_path': '/trainings', // (optional)
'iat': int(datetime.now().timestamp()),
'exp': int((datetime.now() + timedelta(minutes=2)).timestamp())
}

headers = {
'Content-Type': 'application/json',
'Authorization': f"Bearer {workramp_api_key}"
}

body = {
'jwt': jwt.encode(raw_jwt, ia_secret_key, algorithm='HS512')
}

url = f"https://app.workramp.com/api/v1/academies/{your_academy_id}/instant_auth_request"

resp = requests.post(url, headers=headers, data=json.dumps(body))

print("Here is an Instant Auth URL for this user, valid for the next 2 minutes:\n")

print(resp.json()['absoluteLoginUrl']) # this is the URL where you can send the learner
print("\n")

Node.js

Here we’re using the library npm: jsonwebtoken to create our JWT, as well as npm: node-fetch, although you could easily adapt this to use any HTTP library you wanted.

const jwt = require('jsonwebtoken');
const fetch = require('node-fetch');

const rawJwt = {
name: 'Test User',
sub: 'test@user.com',
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + (60 * 2), // 2 minutes from now
dest_path: '/trainings' // optional
};

const apiToken = 'your_api_token_here';
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiToken}`
};

const body = {
jwt: jwt.sign(rawJwt, 'your_secret_key_here', { algorithm: 'HS512' })
};

const academyId = 'your_academy_id_here';
const url = `https://app.workramp.com/api/v1/academies/${academyId}/instant_auth_request`;

fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => {
const absoluteLoginUrl = data.absoluteLoginUrl;
console.log(absoluteLoginUrl); // this is the URL where you can send the learner
})
.catch(error => {
console.log(error);
});

Kotlin

In this code, we're using the io.jsonwebtoken library to create and sign the JWT token. We're also using the khttp library to send the POST request to the API endpoint. Note that you'll need to add the following dependencies to your build.gradle file to use these libraries:

dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.2'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.2'
implementation 'com.github.kittinunf.fuel:fuel:2.2.1'
implementation 'com.github.kittinunf.fuel:fuel-json:2.2.1'
}
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.SignatureAlgorithm
import org.json.JSONObject
import java.time.Instant

fun main() {
val academyId = "your_academy_id_here"
val apiUrl = "https://app.workramp.com/api/v1/academies/$academyId/instant_auth_request"
val apiToken = "your_api_token_here"
val secretKey = "your_secret_key_here"

val rawJwt = JSONObject()
.put("name", "Test User")
.put("sub", "test@user.com")
.put("iat", Instant.now().epochSecond)
.put("exp", Instant.now().plusSeconds(120).epochSecond) // 2 minutes from now
.put("dest_path", "/trainings") // optional

val jwt = Jwts.builder()
.setPayload(rawJwt.toString())
.signWith(SignatureAlgorithm.HS512, secretKey.toByteArray())
.compact()

val headers = mapOf(
"Content-Type" to "application/json",
"Authorization" to "Bearer $apiToken"
)

val body = JSONObject()
.put("jwt", jwt)

val response = khttp.post(
url = apiUrl,
headers = headers,
json = body
)

val absoluteLoginUrl = response.jsonObject.getString("absoluteLoginUrl")
println(absoluteLoginUrl)
}

Ruby

In this code, we're using the jwt gem to create and encode the JWT token. We're also using net/http to send the POST request to the API endpoint. Note that we're using use_ssl: true since the API endpoint uses HTTPS. You could also use any other HTTP library that you like.

require 'jwt'
require 'json'
require 'net/http'

academy_id = 'your_academy_id_here'
api_url = "https://app.workramp.com/api/v1/academies/#{academy_id}/instant_auth_request"
api_token = 'your_api_token_here'
secret_key = 'your_secret_key_here'

raw_jwt = {
'name' => 'Test User',
'sub' => 'test@user.com',
'iat' => Time.now.to_i,
'exp' => (Time.now + 120).to_i, # 2 minutes from now
'dest_path' => '/trainings' # optional
}

jwt = JWT.encode(raw_jwt, secret_key, 'HS512')

headers = {
'Content-Type' => 'application/json',
'Authorization' => "Bearer #{api_token}"
}

body = { 'jwt' => jwt }.to_json

uri = URI(api_url)
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Post.new(uri)
request.body = body
headers.each do |key, value|
request[key] = value
end
http.request(request)
end

login_url = JSON.parse(response.body)['absoluteLoginUrl']
puts login_url

C#

var now = DateTime.UtcNow;
var expirationTime = now.AddMinutes(1);

var claims = new Claim[]
{
new (JwtRegisteredClaimNames.Name, "Jane Doe"),
new (JwtRegisteredClaimNames.Sub, "jane.doe@wr"),
new (JwtRegisteredClaimNames.Iat, new DateTimeOffset(now).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer32),
new (JwtRegisteredClaimNames.Exp, new DateTimeOffset(expirationTime).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer32),
// new Claim("workramp_custom_fields", JsonConvert.SerializeObject(customFields)),
};

var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtToken));
var cred = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha512);//HmacSha512//HmacSha512Signature
var token = new JwtSecurityToken(
claims: claims,
expires: expirationTime,
signingCredentials: cred
);
var jwt = new JwtSecurityTokenHandler().WriteToken(token);
var options = new RestClientOptions(WorkRampUrlPrefix + AcademyId + "/instant_auth_request");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer " + AccessToken);
var jwtPayload = new WorkRampJwtPayload
{
jwt = jwt,
};
request.AddJsonBody(JsonConvert.SerializeObject(jwtPayload));
var workRampResponse = client.Post(request);

Redirect

You can set it up for users to get redirected to your platform. You can designate the exact redirect URL in the Instant Auth configuration settings in WorkRamp. Click Enable Instant Auth and you'll see the field to designate the redirect URL (aka your app platform login).

Academy URL with Instant Auth Flow

When using a WorkRamp Academy URL domain to work with instant auth outside of an app button, our team recommends creating a unique protected destination within your site and set this URL as the redirect destination in WorkRamp. This destination can provide context to the authentication flow about the origin and therefore intent of the user (to access the Academy).

  1. User accesses Academy URL.

  2. Not knowing who the user is yet, we send her to something like https://academypage.com/academy-login

  3. Since this is a login protected page, you ask them to login via any login option

  4. After successfuly login, dropped where they were trying to access, in this case on /academy-login

  5. Knowing who the user is now, you can make a request to WorkRamp for an Instant Auth Link

  6. Then you can redirects them to the URL we provide as response to the request in step 5

  7. User is now on the Academy page and is logged in

Note: If at Step 3 your site recognizes that the user does have an active session, the flow should skip to step 5.

Locking Custom Registration Fields

If you are syncing over Custom Fields via Instant Auth and do not want users to be able to manually edit these fields, you can lock the fields using the "Locked" checkbox for the field on the Registration Settings page.

Did this answer your question?