To link your users with Tanker's client-side SDK, you need to create and provide Tanker identities to your users.

This is done on your application's server and requires the app ID and app secret that you get when you create your app on the Tanker dashboard.

Identity SDKs

To help you manage identities, Tanker provides an identity SDK in the following languages:

If the language your server is implemented in is not in the list, please feel free to reach out to us at contact@tanker.io

Create user identities

Tanker identities should be generated for each of your users when they log in with Tanker for the first time, and stored permanently alongside user records in your app's database.

Creating an identity requires a unique and immutable identifier for each user. If you already have such identifiers in your project, it is advised to reuse them here. Identities must be created only once, which means you must always send the same identity to a given user.

Warning

An identity contains sensitive data, it must only be served to its associated user, after authentication.

It should look something like this:

import (
  "github.com/TankerHQ/identity-go/identity"
)

tankerConfig := identity.Config {
  AppID: "YOUR_APP_ID",
  AppSecret: "YOUR_APP_SECRET",
}

func authenticate(userId: string) (*User, error) {
  // Verify user's authentication
  if err := authenticateUser(userId) {
    return err
  }

  user := database.GetUser(userId)
  if user.Identity == nil {
    user.Identity, _ = identity.Create(tankerConfig, userId)
    database.SaveUser(user)
  }
  return user, nil
}

const tanker = require('@tanker/identity');

const appId = 'YOUR_APP_ID';
const appSecret = 'YOUR_APP_SECRET';


authenticate = async (userId) => {
  // Verify user's authentication
  if (!authenticateUser(userId)) {
    throw 'Invalid authentication for user';
  }

  let user = await database.getUser(userId);
  if (!user.identity) {
    user.identity = await tanker.createIdentity(appId, appSecret, usreId);
    await database.saveUser(user);
  }
  return user
});

Validate an identity

In some cases, the identity has been generated by your server, but has not been registered client-side, for instance if the user did not confirm their email address. This can cause races and incorrect behaviour.

To make sure that the identity has been registered client-side, create a new route on your server, called after the user successfully starts their Tanker session and store a validated flag alongside the user's identity.

func validateIdentity(userID: string) (error) {
  user := database.GetUser(userId)
  user.Validated = true
  database.SaveUser(user)
}

validateIdentity = async (userId) => {    
  let user = await database.getUser(userId);
  user.validated = true;
  await database.saveUser(user);
});

Get public identities

Tanker public identities represent a user for others. It must be distributed to any other user who needs to share with them.

A Tanker public identity can be derived from a user's identity, using the identity package's GetPublicIdentity method. This can only be done if the user already has a Tanker identity. If they don't, or if their identity wasn't validated yet, you need to generate a provisional identity for them.

import (
  "github.com/TankerHQ/identity-go/identity"
)

tankerConfig := identity.Config {
  AppID: "YOUR_APP_ID",
  AppSecret: "YOUR_APP_SECRET",
}

func getPublicIdentity(email: string) (*string, error) {
  user := database.GetUserByEmail(email)
  identity := user.Identity

  if identity == nil || !user.Validated {
    identity = user.ProvisionalIdentity

    if identity == nil {
      user.ProvisionalIdentity = identity.CreateProvisional(tankerConfig, email)
      database.saveUser(user)
      identity = user.ProvisionalIdentity
    }
  }
  return identity.GetPublicIdentity(identity)
}

const tanker = require('@tanker/identity');

const appId = 'YOUR_APP_ID';
const appSecret = 'YOUR_APP_SECRET';


getPublicIdentity = async (email) => {
  const user = await database.getUserByEmail(email);
  let { identity } = user;

  if (!identity || !user.validated) {
    identity = user.provisionalIdentity;
    if(!identity) {
        user.provisionalIdentity = await tanker.createProvisionalIdentity(appID, email);
        await database.saveUser(user);
        identity = user.provisionalIdentity;
    }
  }
  const publicIdentity = await tanker.getPublicIdentity(identity);
  return publicIdentity;
});