Laravel and PHP
Sign Ticketping identity tokens in Laravel or plain PHP with firebase/php-jwt.
You’ll add one route that signs a token with firebase/php-jwt. The example is Laravel; plain PHP is at the end.
Install php-jwt
composer require firebase/php-jwtSet the secret
Get the identity secret from Settings → API → Identity secret and add it to .env. It’s the same value everywhere.
TICKETPING_IDENTITY_SECRET=tpis_...Read it through config, so it still works after php artisan config:cache.
config/services.php:
<?php
return [
'ticketping' => [
'identity_secret' => env('TICKETPING_IDENTITY_SECRET'),
],
];Add the route
routes/web.php:
<?php
use Firebase\JWT\JWT;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::post('/api/ticketping-token', function (Request $request) {
$user = $request->user();
$claims = array_filter([
'sub' => (string) $user->id,
'email' => $user->email,
'name' => $user->name,
'exp' => time() + 300,
], fn ($value) => $value !== null && $value !== '');
$token = JWT::encode($claims, config('services.ticketping.identity_secret'), 'HS256');
return response($token)->header('Content-Type', 'text/plain');
})->middleware('auth');- The
authmiddleware stops signed-out requests. array_filterdrops an emptyemailorname, because Ticketping refusesnullclaims.- It’s in
routes/web.phpso it uses your normal session login. If your frontend authenticates with Sanctum tokens, put it inroutes/api.phpwithauth:sanctuminstead.
Call it from your layout
Laravel checks the CSRF token on POST. Send it from a meta tag, and send X-Requested-With so that Laravel answers 401 instead of redirecting to the login page when the session has ended.
<meta name="csrf-token" content="{{ csrf_token() }}">
@auth
<script>
window.Ticketping ||= (...args) => (Ticketping.q ||= []).push(args)
Ticketping('identify', {
userId: @json((string) auth()->id()),
email: @json(auth()->user()->email),
name: @json(auth()->user()->name),
getToken: async () => {
const res = await fetch('/api/ticketping-token', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
'X-Requested-With': 'XMLHttpRequest'
}
})
if (!res.ok) throw new Error(`Ticketping token request failed (${res.status})`)
return res.text()
}
})
</script>
@endauth
<script src="https://widget.ticketping.com/v2/loader.js" data-key="pk_..." async></script>Call Ticketping('logout') when the user signs out.
Plain PHP
Without a framework, the same signing code works in any script that knows the signed-in user:
<?php
use Firebase\JWT\JWT;
require __DIR__ . '/vendor/autoload.php';
session_start();
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || empty($_SESSION['user'])) {
http_response_code(401);
exit;
}
$user = $_SESSION['user'];
$claims = array_filter([
'sub' => (string) $user['id'],
'email' => $user['email'] ?? null,
'name' => $user['name'] ?? null,
'exp' => time() + 300,
], fn ($value) => $value !== null && $value !== '');
header('Content-Type: text/plain');
echo JWT::encode($claims, getenv('TICKETPING_IDENTITY_SECRET'), 'HS256');Check that it works
- Sign in on localhost and run this in the browser console:
await (await fetch('/api/ticketping-token', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
'X-Requested-With': 'XMLHttpRequest'
}
})).text()- Paste the token into the token validator under Settings → API → Identity secret. It shows the claims, or says exactly what to fix.
- Reload and send a message. The dashboard shows it with the user’s name and a Verified badge.
A 419 means the CSRF token is missing.
Copy prompt for your AI coding agent
Add Ticketping identity verification (chat widget v2) to this Laravel (or PHP) app.
Docs index: https://ticketping.com/llms.txt
This page as Markdown: https://ticketping.com/docs/identity-laravel.md
1. composer require firebase/php-jwt.
2. Add 'ticketping' => ['identity_secret' => env('TICKETPING_IDENTITY_SECRET')] to config/services.php,
and TICKETPING_IDENTITY_SECRET= to .env.example. Never commit the value.
3. Add the POST /api/ticketping-token route exactly as on the docs page, behind the auth middleware: claims
sub (string user id), email, name (dropped when empty), exp = time() + 300, signed with
JWT::encode($claims, config('services.ticketping.identity_secret'), 'HS256'), returned as text/plain.
4. In the main layout, add the csrf-token meta tag and, inside @auth, the queue stub and
Ticketping('identify', { userId, email, name, getToken }) where getToken POSTs with the X-CSRF-TOKEN and
X-Requested-With: XMLHttpRequest headers and returns res.text(). Add the loader script with data-key="pk_..."
and ask me for the publishable key. Call Ticketping('logout') on sign-out.
5. Tell me how to verify with the token validator at Settings → API → Identity secret.