認証機能付きで、生放送を提供する

前回、生放送を試してみるを書きましたが、配信元がサーバーを指定すれば、無制限に配信ができてしまいます。
今回は、配信元を認証して生放送をしてみます。

目次

参考

やること

nginx-rtmp-module の認証機能を rails で構築する。

動作環境

  • CentOS7.7
  • Ruby2.5.8(rbenv にて導入)

rails 実装

認証機能がほしいので devise を導入し、RTMP の情報へのリレーションを用意します。
(rails 6.0 系の環境構築がしんどかったのは別の話)

認証ログイン機能は、devise で提供するので省略。
RTMP 配信で用いるストリームキーを任意に発行させる仕組みを用意します。
ユーザーの関連情報なので、UserDetail モデルとしました。

/auth-app/app/controllers/user_details_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class UserDetailsController < ApplicationController
before_action :authenticate_user!
def show
@key = current_user&.user_detail&.streem_key

end

def edit
@key = UserDetail.find_or_create_by(user_id: current_user.id)
end

def update
@key = UserDetail.find(params[:id])
if @key.update(user_details_param)
redirect_to :action => 'show'
else
render :edit
end
end

private
def user_details_param
params.fetch(:user_detail, {}).permit(:streem_key)
end
end

加えて nginx が問い合わせる API 部分を実装します。

/auth-app/app/controllers/auth_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class AuthController < ApplicationController
def test
user_detail = UserDetail.find_by(streem_key: params[:name])

if user_detail.present?
user_detail.broadcast_state=true
user_detail.save()
render status: 200, json: { status: 200, message: 'OK' }
else
render status: 400, json: { status: 400, message: 'NG' }
end
end

def update
user_detail = UserDetail.find_by(streem_key: params[:name])

if user_detail.present?
render status: 200, json: { status: 200, message: 'OK' }
else
render status: 400, json: { status: 400, message: 'NG' }
end
end

def done
user_detail = UserDetail.find_by(streem_key: params[:name])

if user_detail.present?
user_detail.broadcast_state=false
user_detail.save()
end

render status: 200, json: { status: 200, message: 'OK' }
end
end

ストリームキーが user_etails テーブルの中にあるか検証し、ステータスコード 200 か 400 を返します。

ルーティングは次のようにします。

/auth-app/config/routes.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Rails.application.routes.draw do
# ユーザー認証
devise_for :users
 # RTMP用のuser関連情報
resources :user_details, only: [:show,:update,:edit]
resources :viewers, only: [:index,:show]

# nginxが問い合わせるAPI
get "test", to: "auth#test"
get "done", to: "auth#done"
get "update", to: "auth#update"

# ログイン前後のホーム画面
get 'home/index'
root to: "home#index"
end

nginx 側設定

Rails で API を作成したので、nginx が問い合わせするように設定します。

/etc/nginx/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
user  root;
worker_processes 1;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';


access_log /var/log/nginx/access.log main;

sendfile on;

keepalive_timeout 65;

gzip on;

server {
listen 80;
server_name localhost;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

location /live {
root /html;
}
location /viewer.html {
root /html;
}

location /{
proxy_pass http://127.0.0.1:3000;
}
}
}
rtmp {
server{
listen 1935;
access_log /var/log/nginx/rtmp_access.log combined;

application live{
live on;
# publishイベントをhttp://127.0.0.1:3000/testに通知する。200以外の時配信元にエラーを出す
on_publish http://127.0.0.1:3000/test;
on_publish_done http://127.0.0.1:3000/done;
on_update http://127.0.0.1:3000/update;

notify_method get;

hls on;
hls_path /html/live;

hls_cleanup off;

# rtmpで配信しない
deny play all;

}

}
}

確認

nginx の設定を反映し、Rails アプリケーションを起動し確認します。
(動作確認が目的なので、見た目が適当なのはご愛嬌。)
今回も、配信元はOBSを使用します。

http://「対象のサーバー」にアクセスすると次の画面になります。

ログインすると「配信 key」のリンクが出てきます。

開くと現在の配信キーが確認できます。

この時点では、配信キーを「video001」設定して配信できます。

編集ができるので、「video00100」にします。

この時点では、配信キーが変わっているので、しばらくするとエラーで配信が停止します。
再読み込みしても、配信されていません。
配信元の OBS で配信キーを「video00100」に設定することで配信できるようになります。

また、別途生放送の一覧ページを作ったので生放送中なのかわかるようにしました。

正規の終了を通過していれば、「停止中」が表示されます。

配信キーを任意に発行して、制限ができるようになりました。


認証機能付きで生配信をやってみました。

本当は devise で登録した ID とパスワードも含めて検証したかったのですが、リクエストクエリの中に載ってきませんでした
OBS の設定項目にはあるのに。
また別途調べる予定です。

ではでは。