Higher Logic Vanilla (Vanilla) offers several client libraries that you can use on your site if you're implementing jsConnect. If your site is programmed in a different language or you can't use one of Vanilla's libraries, this article explains how to implement the protocol.
What you'll need
To implement jsConnect, you'll need to create an authentication page on your site that gives details of the currently signed in user. The jsConnect v3 protocol uses JSON Web Tokens (JWT) to secure the SSO.
✔️ TIP: We highly recommend using an existing JWT library to verify and create JWTs.
Vanilla uses the HMAC SHA256 algorithm to sign tokens, so you need to have a library that can implement that hash algorithm at a minimum.
Authentication workflow
Here's an example of a typical log in workflow using jsConnect v3:
- A user clicks the Sign In link in your Vanilla community, which points to our
jsconnect-redirect
endpoint with:- The
client_id
of the jsConnect application you entered in the Vanilla Dashboard and - The
Target
value, which is the path of the current page.
jsconntect-redirect
generates State data and the Return URL, and compiles it into a JWT. The payload of the state includes the:- Target (e.g., `"t" : "/discussions"`) and,
- The "nonce," a random hash that is returned to us to confirm integrity of the communication (e.g., `"n" : "MXet9yoFxkVvzUCpzICj"`)
- The user is redirected back to Return URL, which was passed in the JWT (e.g., `rurl : "https://myforums.com/entry/jsconnect"`) with the JWT response in the URL fragment (see Redirect back to Vanilla with your response below).
- Your system generates a JWT response (see Generate a JWT with your response below).
- The user logs in on your system or your system detects that user already has an authenticated session on your system.
- User is then 302-redirected to the Sign In URL you configured in your Vanilla Dashboard with the
jwt
as a GET parameter (e.g., https://myssite.com/signin?jwt=eyJraWQiOiJzdHViX...bqP0lI).
Authentication page process
Your authentication page will do the following:
- Verify the jsConnect request from Vanilla.
- Generate a JWT with your response and the current user's information.
- Redirect back to Vanilla with your response.
Verify the jsConnect request from Vanilla
Vanilla sends its request in the querystring under the jwt
parameter. The value of the parameter is a JWT, and you need to verify it with the following process:
- Verify the JWT with your library. The secret is the one you configured in Vanilla under the jsConnect connection.
- Make sure the JWT has an
rurl
claim. This claim is the URL that you need to redirect back to.
Generate a JWT with your response
Your response should have the following fields:
// header
{
"kid": "jsConnect client ID"
}
// payload
{
"v": "lang:1.0", // version information
"iat": 1586349451, // current unix timestamp
"exp": 1586350051, // expiry, no more than 10 minutes from now
"u": {}, // your user or an empty object if not signed in
"st": {}, // this is the "st" field from the request
}
The User field
Your user information goes in the u
field of your JWT's payload. It can contain the following standard fields:
{
"id": "12345", // database ID that identifies your user
"name": "username", // username of your user
"email": "user@example.com", // email address
"photoUrl": "https://example.com/avatar.jpg", // avatar
"roles": [] // array of role names or IDs
}
- Only the
id
field is required, but you typically want to pass some or all of the other fields. - If there is no user signed into your system, just put an empty object in the user field.
The State field
The state goes in the st
field of your JWT's payload. This field comes from the request, and is necessary to secure the SSO.
The Version field
The version goes in the v
field of your JWT's payload. We like to use the convention language:version
for this field to give both the language the library was written in and its specific version number. Adding a version greatly helps with troubleshooting, so we highly recommend you add it.
Redirect back to Vanilla with your response
Once you've verified the request and generated your response token, you need to 302-redirect back to Vanilla. Your redirect URL takes the following format:
<redirect url>#jwt=<response jwt>
- For the redirect URL, you need to use the
rurl
that came in the payload from the request. Do not hard code this URL, as it may change in the future. - For the response JWT, you use the JWT that you generated in step 2 above.
📝 NOTE: For the response, the JWT is transmitted in the fragment rather than the querystring. This is to provide another layer of security so that specific authentication tokens don't show up in server logs.
Troubleshooting and tips
Here are a few tips for troubleshooting your jsConnect integration. The first step to troubleshooting your connection is to use the Test feature in the jsConnect Addon in the Dashboard.
Validate your JWT response
When you test your jsConnect connection in the Dashboard, you can retrieve the JWT response you're sending and test it by pasting it in the "Encoded" field at jwt.io
"Nonce not Found"
If you receive a "Nonce not Found" error message when trying to connect to the community, verify your response token. If you're not using one of our libraries to generate your jsConnect response you may be using a library that handles the State value differently. The state (`st`) in the payload of your response to Vanilla needs to return the same 'nonce' (`n`) that Vanilla sent to you:
{
"u": {
"id": "457",
"name": "User",
"email": "user@example.com",
"roles": "Expert"
},
"st": {
"n": "FNWewhMzGuPeyrY_xStY"
},
"v": "php:3",
"iat": 1589231685,
"exp": 1589232285
}
Token Expired
If you receive a jsConnect request with an expired JWT token (exp
< now()) or no nonce (n
) output an error instructing the user to log in again. Do not redirect them back to your site automatically, as this could cause a loop in some cases.
User Does Not Exist
If someone initiates a login with jsConnect but the user does not exist or fails to log in, you can send them back to the community flagged as a guest by invoking the setGuest()
method that should exist in your jsConnect library. In PHP this would be: JsConnect::setGuest()
.
Reference implementation
This article explains how to implement jsConnect v3. If you learn better by reading code, we recommend you reference our PHP implementation.