Initial commit: Animexe Laravel platform
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
class AgoraTokenService
|
||||
{
|
||||
private const VERSION = '006';
|
||||
private const PRIVILEGE_JOIN_CHANNEL = 1;
|
||||
private const PRIVILEGE_PUBLISH_AUDIO_STREAM = 2;
|
||||
private const PRIVILEGE_PUBLISH_VIDEO_STREAM = 3;
|
||||
private const PRIVILEGE_PUBLISH_DATA_STREAM = 4;
|
||||
|
||||
public static function generateToken(string $channelName, int $uid, int $expireSeconds = 3600): string
|
||||
{
|
||||
$appId = config('services.agora.app_id', env('AGORA_APP_ID', ''));
|
||||
$appCertificate = config('services.agora.app_certificate', env('AGORA_APP_CERTIFICATE', ''));
|
||||
|
||||
if (!$appId || !$appCertificate) {
|
||||
// Development fallback — no token required when cert is empty
|
||||
return '';
|
||||
}
|
||||
|
||||
$currentTimestamp = time();
|
||||
$expireTimestamp = $currentTimestamp + $expireSeconds;
|
||||
|
||||
$nonce = random_int(1, 16777216);
|
||||
|
||||
$privileges = [
|
||||
self::PRIVILEGE_JOIN_CHANNEL => $expireTimestamp,
|
||||
self::PRIVILEGE_PUBLISH_AUDIO_STREAM => $expireTimestamp,
|
||||
self::PRIVILEGE_PUBLISH_VIDEO_STREAM => 0,
|
||||
self::PRIVILEGE_PUBLISH_DATA_STREAM => $expireTimestamp,
|
||||
];
|
||||
|
||||
// Pack message
|
||||
$message = self::packUint16(1); // version: 1 (AccessToken)
|
||||
$message .= self::packUint32($currentTimestamp);
|
||||
$message .= self::packUint32($nonce);
|
||||
$message .= self::packString($channelName);
|
||||
$message .= self::packUint32($uid);
|
||||
$message .= self::packPrivileges($privileges);
|
||||
|
||||
// HMAC-SHA256 signature
|
||||
$signature = hash_hmac('sha256', $appId . $currentTimestamp . $nonce . $channelName . $uid . self::packPrivileges($privileges), $appCertificate, true);
|
||||
|
||||
$content = self::packString($signature) . $message;
|
||||
|
||||
return self::VERSION . $appId . base64_encode($content);
|
||||
}
|
||||
|
||||
private static function packUint16(int $v): string
|
||||
{
|
||||
return pack('n', $v);
|
||||
}
|
||||
|
||||
private static function packUint32(int $v): string
|
||||
{
|
||||
return pack('N', $v);
|
||||
}
|
||||
|
||||
private static function packString(string $v): string
|
||||
{
|
||||
return pack('n', strlen($v)) . $v;
|
||||
}
|
||||
|
||||
private static function packPrivileges(array $privileges): string
|
||||
{
|
||||
ksort($privileges);
|
||||
$packed = pack('n', count($privileges));
|
||||
foreach ($privileges as $key => $value) {
|
||||
$packed .= pack('n', $key) . pack('N', $value);
|
||||
}
|
||||
return $packed;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user