Документация Flussonic Media Server

Contents

Защита доступа к потокам (Авторизация по токену)

В этой статье приведен пример того, как можно реализовать систему авторизации без написания собственного бэкенда.

Схема работы авторизации:

  1. Ваш сайт генерирует токен по несложной формуле и хеширует его с помощью секретного ключа.
  2. Клиент открывает поток с полученным токеном.
  3. Flussonic генерирует токен по той же формуле, используя тот же ключ (и дополнительно используя имя потока и IP адрес клиента).
  4. Хеши совпали — доступ разрешен. Не совпали — запрещен.

Настройка Flussonic для использования авторизации по токену

В поставке Flussonic есть файл со всей необходимой логикой (скрипт 'securetoken'). Нужно лишь указать путь к нему в директиве auth:

stream example-stream {
  url fake://fake;
  auth securetoken://SECRETKEY;
}

Можно включить авторизацию (директиву auth) как для одного потока, так и глобально.

Код для сайта

Чтобы сгенерировать токен, Flussonic должен знать следующее:

  • IP-адрес клиента
  • Имя потока
  • Секретный ключ
  • Текущее время

Код на сайте должен собрать в одну строку эти данные:

string = streamname + ip + starttime + endtime + secretkey + salt

И получить токен по формуле:

sha1(string) + salt + endtime + starttime.

Где:

  • ip — IP адрес клиента.
  • name — название потока.
  • starttime — обычно это текущее время UTC (в Unix Timestamp).
  • endtime — время окончания жизни токена, обычно это текущее время + несколько часов. По прошествии этого времени токен перестанет работать и его надо будет запрашивать заново.
  • secretkey — это ключ, указанный в файле /etc/flussonic/flussonic.conf.
  • salt — строка из случайных символов, необходима, чтобы для одинаковых входных данных генерировались разные токены.

PHP пример

<?php

$flussonic = 'http://flussonic-ip'; // flussonic address
$key = 'SECRETKEY'; // key from flussonic.conf file. KEEP IT IN SECRET
$lifetime = 3600 * 3; // 3 hours after link will be invalid

$stream = $_GET['stream']; // this script get streamname from a query string (script.php?stream=bbc)

$ipaddr = $_SERVER['REMOTE_ADDR'];
$desync = 300; // allowed time desync between flussonic and hosting servers in seconds
$starttime = time() - $desync;
$endtime = $starttime + $lifetime;
$salt = bin2hex(openssl_random_pseudo_bytes(16));

$hashsrt = $stream.$ipaddr.$starttime.$endtime.$key.$salt;
$hash = sha1($hashsrt);

$token = $hash.'-'.$salt.'-'.$endtime.'-'.$starttime;
$link = $flussonic.'/'.$stream.'/embed.html?token='.$token;
$embed = '<iframe allowfullscreen style="width:640px; height:480px;" src="'.$link.'"></iframe>';

echo $embed;

Rails пример

config/routes.rb:

Rails.application.routes.draw do
 ...
  get '/securetoken/:id', to: 'securetoken#index'
end

app/controllers/securetoken_controller.rb:

class SecuretokenController < ApplicationController

  def index

    flussonic = 'http://flussonic-ip'
    secret = 'SECRETKEY'

    streamname = params[:id]
    lifetime = 3600 * 3
    starttime = Time.now.to_i - 300
    endtime = Time.now.to_i + lifetime
    salt = rand(8**8).to_s(8)

    hash = Digest::SHA1.hexdigest(streamname + request.remote_ip + starttime.to_s + endtime.to_s + secret + salt)
    token = hash + '-' + salt + '-' + endtime.to_s + '-' + starttime.to_s
    @url = flussonic + '/' + streamname + '/' + 'embed.html?token=' + token
  end
end

app/views/securetoken/index.html.erb:

<iframe allowfullscreen style="width:640px; height:480px;" src="<%= @url %>"></iframe>