Tribe Community Platform

The Tribe Community Platform Developer Hub

Welcome to the Tribe Community Platform developer hub. You'll find comprehensive guides and documentation to help you start working with Tribe Community Platform as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started    

Although OAuth2 is the most recommended way of authenticating your members to community, JWT SSO is the easiest way if your website does not support OAuth2. You should be able to implement it by adding a few lines of code to your website or product.

In this method, you'll sign a JSON Web Token (JWT) with User's information using a private key. Then the generated token should be passed as jwt in the query string to Tribe.

To generate the JWT token, first you need to get your Single Sign-On private key. Login to your community as an Admin. In the Admin Panel under Apps, install the "JWT SSO" app and you should find the Single Sign-On private key there.

🚧

JWT SSO app should not be confused with JWT Authorization app. The "JWT Authorization" app is used to authenticate API requests using JWT Tokens and is not relevant to single sign-on.

Next, you should first install a JWT library:

npm install --save jsonwebtoken
composer require firebase/php-jwt
# See instructions here:
https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt/0.7.0
pip install PyJWT
sudo gem install jwt

Then use the following source code and the SSO private key inside the Tribe "JWT SSO" app to generate the JWT token:

var jwt = require('jsonwebtoken');

var privateKey = '{Your Private Key}';

function createToken(user) {
  var userData = {
    email: user.email,
    sub: user.id,
    name: user.name,
    iat: Math.round(new Date().getTime() / 1000), // token issue time
    exp: Math.round(new Date().getTime() / 1000) + 60, // token expiration time
    picture: user.picture, // optional but preferred
    locale: user.locale, // optional
    title: user.title, // optional
    bio: user.bio, // optional
    groups: [] // optional, more details under JWT Supported Keys
  };
  return jwt.sign(userData, privateKey, {algorithm: 'HS256'});
}
use FirebaseJWTJWT;

const privateKey = '{Your Private Key}';

function createToken($user) {
  $userData = [
    'email' => $user['email'],
    'sub' => $user['id'],
    'name' => $user['name'],
    'picture' => $user['picture'], // optional but preferred
    'locale' => $user['locale'], // optional
    'title' => $user['title'], // optional
    'bio' => $user['bio'], // optional
  ];
  return JWT::encode($userData, privateKey, 'HS256');
}
import java.util.HashMap;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class TokenCreator {
  private static final String privateKey = "{Your Private Key}";

  public static String createToken(User user) throws Exception {
    HashMap<String, Object> userData = new HashMap<String, Object>();
    userData.put("email", user.email);
    userData.put("sub", user.id);
    userData.put("name", user.name);
    userData.put("picture", user.picture); // optional but preferred
    userData.put("locale", user.locale); // optional
    userData.put("title", user.title); // optional
    userData.put("bio", user.bio); // optional

    return Jwts.builder()
               .setClaims(userData)
               .signWith(SignatureAlgorithm.HS256, privateKey.getBytes("UTF-8"))
               .compact();
  }
}
import jwt

private_key = '{Your Private Key}'

def create_token(user):
  user_data = {
    'email': user.email,
    'sub': user.id,
    'name': user.name,
    'picture': user.picture, # optional but preferred
    'locale': user.locale, # optional    
    'title': user.title, # optional
    'bio': user.bio, # optional
  }
  return jwt.encode(user_data, private_key, algorithm='HS256')
require 'jwt'

privateKey = '{Your Private Key}'

def createToken(user)
  userData = {
    :email => user[:email],
    :sub => user[:id],
    :name => user[:name],
    :picture => user[:picture], # optional, but preferred
    :locale => user[:locale], # optional
    :title => user[:title], # optional
    :bio => user[:bio], # optional
  }

  JWT.encode(userData, privateKey, 'HS256')
end

Finally, you should pass the generated JWT token to Tribe as followed:

<<community_url>>/auth/sso?jwt=[Generated SSO Token]&redirect=/answers

Tribe will create the user using the provided information in the JWT and log them in if the user does not already exist. If the user exists, it will update user's information and log them in.

Identifying user's existence

Tribe will first try to find the user using provided sub. It will check if any user has externalId equal to provided sub. If the user is found, it will update their information including their email address.

If no user is found based on externalId == sub, it will try to find the user using the email address provided and connects the user's externalId to the provided sub.

❗️

If a user with externalId == sub check does not exist and the user matching with email already has an externalId, Tribe will through a conflict error.

In this case, you may want to update existing users externalId or email using "Update a Specific User" API.

JWT Supported Keys

Tribe JWT SSO supports all standard JWT fields including sub, aud, exp, and iat. Here you can find all fields supported in the JWT:

  • sub (required): The ID of the user. It will be stored as externalId in Tribe's user object. Please note that the primary key of the user at Tribe is stored as _id and is a 24 hexadecimal character string. In most of the API requests, you can query the user by Tribe id or the externalId (e.g. /api/v1/users/external:{externalId}).
  • name (required): Name of the user.
  • email (required): The email of the user. This email address is considered as a verified address. You should make sure you're verifying it on your side.
  • exp: The expiration time of the JWT. Although this value is not required, it's highly recommended to set it to 60 seconds from now. If it's not set, the token will be valid forever and can introduce security issues.
  • role: User's role in the community. Can be member (default), moderator, or admin.
  • picture: A full URL to user's profile picture. It should include https:// or http://. Tribe will not validate this field, so you should make sure it's a valid URL on your side.
  • source: You can pass a source to identify where the user came from for marketing purposes (similar to utm_source).
  • title: The title of the user used in their profile.
  • bio: A short description of the user. Can include simple HTML code.
  • locale: The locale of the user. By default, it's set to en. This option is only available for enterprise clients.
  • groups: You can pass an array of Tribe groups the user should be joined to as an array. It can be an array of Tribe group IDs, or an array of object:
[
    {
        "group": "{tribeGroupId}",
        "role": "member",
        "status": "joined", // Can be unapproved or joined
    }
]
  • groupsOperation: By default, when you pass groups array, it'll replace user's groups with the array passed as an option. This is perfect when you want to enforce users to be part of specific groups. In many cases, you want to add extra groups instead of replacing them. In this case, you should pass { "groupsOperation": "add" }. Here is an example:
{
    "sub": "test",
    "email": "[email protected]",
    "name": "Test",
    "groups": [
        {
            "group": "{tribeGroupId}",
            "role": "member",
            "status": "joined",
        }
    ],
    "groupsOperation": "add"
}

Updated 2 months ago


JWT SSO


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.