---
url: https://talkjs.com/docs/Features/Security/Authentication/
title: "Authentication | Security | TalkJS Docs"
---

For AI agents: Find a documentation index at https://talkjs.com/llms.txt (full content at https://talkjs.com/llms-full.txt). Get a markdown version of any page by appending .md to its URL path.

# Authentication

Generate and verify tokens to secure your chat.

Authentication helps keep your chat and user data secure. Without authentication:

-   Malicious users can send messages as anyone
-   Malicious users can read anyone's messages
-   Anyone can use the TalkJS API to send messages without using your site

When you first create your TalkJS account, all user authentication is turned off. This makes it easy to get started, but **always enable authentication on all live services**.

This page explains how to enable authentication and protect your user data.

Always enable authentication on any live service. Authentication keeps your user data secure, by ensuring that only legitimate users can connect to your chat.

## 1\. Generate a token

Begin by generating a token. Users can connect to TalkJS by digitally signing a token containing their user ID. TalkJS will reject requests from any users who don't have a valid token.

To generate tokens, copy the relevant code snippet into your backend server and install the library listed on the first line.

**NodeJS**

```javascript
// Uses `jsonwebtoken`: https://www.npmjs.com/package/jsonwebtoken
import jwt from 'jsonwebtoken';

const encoded_jwt = jwt.sign({ tokenType: 'user' }, '<SECRET_KEY>', {
  issuer: '<APP_ID>',
  subject: '<USER_ID>',
  expiresIn: '1d',
});
console.log(encoded_jwt);
```

**Python**

```python
# Uses `PyJWT`: https://pypi.org/project/PyJWT/
import jwt
import time

payload = {
  "tokenType": "user",
  "iss": "<APP_ID>",
  "sub": "<USER_ID>",
  "exp": time.time() + 24 * 3600
}
encoded_jwt = jwt.encode(payload, "<SECRET_KEY>")
print(encoded_jwt)
```

**PHP**

```php
<?php
// Uses `lcobucci/jwt`: https://packagist.org/packages/lcobucci/jwt
use Lcobucci\JWT\Encoding\ChainedFormatter;
use Lcobucci\JWT\Encoding\JoseEncoder;
use Lcobucci\JWT\Signer\Key\InMemory;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Token\Builder;
require 'vendor/autoload.php';

$tokenBuilder = new Builder(new JoseEncoder(), ChainedFormatter::default());
$algorithm = new Sha256();
$signingKey = InMemory::plainText("<SECRET_KEY>_GOES_HERE_REPLACING_THIS_TEXT");

$now = new DateTimeImmutable();
$token = $tokenBuilder
  ->withClaim('tokenType', 'user')
  ->issuedBy('<APP_ID>')
  ->relatedTo('<USER_ID>')
  ->expiresAt($now->modify('+1 days'))
  ->getToken($algorithm, $signingKey)
  ->toString();
echo $token;
```

**Ruby**

```ruby
# Uses `jwt`: https://rubygems.org/gems/jwt
require 'jwt'

payload = {
  tokenType: 'user',
  iss: '<APP_ID>',
  sub: '<USER_ID>',
  exp: Time.now.to_i + 24 * 3600
}
token = JWT.encode payload,
  '<SECRET_KEY>',
  'HS256'
puts token
```

**Java**

```clike
// Uses `java-jwt`: https://mvnrepository.com/artifact/com.auth0/java-jwt
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.JWT;
import java.util.Date;

public class Main {
  public static void main(String[] args) {
    Algorithm algorithm = Algorithm.HMAC256("<SECRET_KEY>");
    String token = JWT.create()
      .withClaim("tokenType", "user")
      .withIssuer("<APP_ID>")
      .withSubject("<USER_ID>")
      .withExpiresAt(new Date(System.currentTimeMillis() + 24 * 3600 * 1000))
      .sign(algorithm);
    System.out.println(token);
  }
}
```

**C#**

```clike
// Uses `jose-jwt`: https://www.nuget.org/packages/jose-jwt/
using Jose;
using System;
using System.Collections.Generic;
using System.Text;

class Program
{
  static void Main(string[] args)
  {
    var epochSeconds = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
    var payload = new Dictionary<string, object>()
      {
        { "tokenType", "user" },
        { "iss", "<APP_ID>" },
        { "sub", "<USER_ID>" },
        { "exp", epochSeconds + 24 * 3600 }
      };
    var secret = Encoding.UTF8.GetBytes("<SECRET_KEY>");
    string token = Jose.JWT.Encode(payload, secret, JwsAlgorithm.HS256);
    Console.WriteLine(token);
  }
}
```

**Go**

```go
package main

import (
  "fmt"
  "time"
)

import "github.com/golang-jwt/jwt/v5"

func main() {
  token := jwt.NewWithClaims(
    jwt.SigningMethodHS256,
    jwt.MapClaims{
      "tokenType": "user",
      "iss": "<APP_ID>",
      "sub": "<USER_ID>",
      "exp": time.Now().Add(time.Day).Unix(),
    })

  secret := []byte("<SECRET_KEY>")
  tokenString, err := token.SignedString(secret)
  fmt.Println(tokenString, err)
}
```

**Elixir**

```elixir
# Uses `joken`: https://hex.pm/packages/joken
# Requires a json library like `jason`: https://hex.pm/packages/jason

# config/config.exs
import Config
config :joken, default_signer: "<SECRET_KEY>"

# lib/talkjs_token.ex
defmodule TalkjsToken do
  use Joken.Config

  def token_config do
    default_claims(
      skip: [:aud, :jti],
      iss: "<APP_ID>",
      default_exp: 24 * 3600
    )
    |> add_claim("tokenType", fn -> "user" end)
  end
end

# lib/main.ex
payload = %{ "sub" => "<USER_ID>" }
token = TalkjsToken.generate_and_sign!(payload)
IO.inspect(token)
```

**Dart**

```dart
// Uses `dart_jsonwebtoken`: https://pub.dev/packages/dart_jsonwebtoken
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';

void main(List<String> arguments) {
  final jwt = JWT(
    {'tokenType': 'user'},
    issuer: '<APP_ID>',
    subject: '<USER_ID>',
  );

  final encoded_jwt = jwt.sign(
    SecretKey('<SECRET_KEY>'),
    expiresIn: Duration(days: 1),
  );

  print(encoded_jwt);
}
```

In the code snippet, replace `<APP_ID>` with your own app ID, and replace `<SECRET_KEY>` with your own secret key. You can find both your app ID and secret key on the **Settings** page of your [TalkJS dashboard](https://www.talkjs.com/dashboard). Then replace `<USER_ID>` with the ID of the user who is connecting to TalkJS.

**Important:** Never include your secret key in frontend code. It gives full admin access to your TalkJS account.

Your generated token should look similar to the following example:

> eyJhbGciOiJIUzI1NiJ9.eyJ0b2tlblR5cGUiOiJ1c2VyIiwiaXNzIjoiRVhBTVBMRV9BUFAiLCJzdWIiOiJFWEFNUExFX1VTRVIifQ.L2xKxkn0mpK46PKP\_S384N0mT1Flog38NAaaiy3nG-I

## 2\. Pass a token

Next, make sure that your users pass their token when connecting to TalkJS. The token is different each time, so you need to set it dynamically. For example, in PHP, you might do:

**JS Data API**

```php
const session = getTalkSession({
  appId: "<APP_ID>",
  userId: "<USER_ID>",
});
session.setToken("<?= $authToken ?>");
```

**Classic SDK**

```php
const session = new Talk.Session({
  appId: "<APP_ID>",
  userId: "<USER_ID>",
  token: "<?= $authToken ?>",
});
```

Alternatively, a static website might send a web request asking your server to generate a token.

Test the solution. If TalkJS stops working once you provide a token, check the developer console for any warnings or error messages. If you're still stuck, send us a message in the chat on this page. Our developers will be happy to help.

## 3\. Enable authentication (identity verification)

Once TalkJS loads without errors when you provide a token, you can enable authentication (identity verification) on the **Settings** page of your [dashboard](https://www.talkjs.com/dashboard/), under **Security settings**. With authentication enabled, only users with a valid token can connect to your chat. Any connections without a valid token get blocked.

## Prevent expired sessions

The example code in this guide generates tokens that expire after 24 hours. If a user keeps the page open for more than 24 hours, TalkJS will stop working and ask them to refresh the page.

To add support for sessions lasting longer than 24 hours, follow the [advanced authentication guide](https://talkjs.com/docs/Features/Security/Advanced_Authentication/#long-life-authentication-setups).
