LoginSignup
1
0

More than 3 years have passed since last update.

tusdとtus-js-client, uppyを使ったファイルアップロードをapache2.4のCentOS7で構築する(cookie編)

Last updated at Posted at 2020-06-28

v2

  • CORSは不要と気がつきましたので、httpd.confの設定は不要だと思います(不具合が出たらまた見直すかもしれませんが)
  • 理由は前回記事をご覧ください。
  • 変更点はv2としています。

目的

環境

  • CentOS7
  • apache 2.4.41
  • browser Firefox77 (MacOS)など
  • tusd v1.0
  • tus-js-client v2

仕組み

  • tusでファイルアップロードする仕組みはクライアント(ブラウザ)からhttps://www.your-site.net/files/にfileをuploadすると宣言して、apacheではリバースプロキシで/files/へのアクセスをhttp://localhost:1080/に変換し、サーバのデーモンtusdがこのポートを監視して、クライアントからのfileを/files/に格納する動きをするものでした。詳しくは前回の記事をご覧ください。
  • このときtusdはファイルを生成するときとファイル処理の完了したときにコマンドを発行する、あるいはhttpで処理することができます。これをhookと呼びます。gitと同じ仕組みだとか。といってもファイルフックはtusdの処理タイミングで決まった名前のコマンド(シェルスクリプト)をキックするというだけです。
  • 取説はこちら:github.com/tusd/.../docs/hooks.md
  • LATS(Linux, Apache, Textfile and Shell-script)ではhttp hookでなく当然file hook(シェルコマンド)を選択します。

フックコマンド

  • 日本語訳をgoogle翻訳ベースにポイントだけ載せておきます。
    • pre-create:アップロード前にトリガーされ、ユーザー確認などができます。アップロードの拒否は終了コードを0以外にするだけです。
    • post-create: アップロード作成後にトリガーされ、新しいアップロードを処理する必要があることをシステムの他の部分に通知します。
    • pre-finish: アップロードが完全に終了した後、クライアントに応答が返される前にトリガーされ、これはブロッキングフックであり、アップロードされたファイルを検証または後処理するために使用できます。0以外の終了コードの場合400、HTTP 500エラーがクライアントに返されます。
    • post-finish: アップロードが完全に終了した後にトリガーされ、すべてのチャンクが転送されストレージに保存されます。このファイルを使用してさらに処理するか、他のアプリケーションにこのアップロードの完了を通知できます。チャンクとはtus固有の用語で分割されアップロードファイルを意味します。参考
    • post-terminate: アップロードが終了した後にトリガーされ、アップロードが完全に停止し、関連チャンクがストレージから完全に削除されています。アップロードのコンテンツを取得できなくなり、このアップロードが再開または終了しないことを他のアプリケーションに通知することができます。
    • post-receive: 実行中のアップロードごとにトリガーされ、現在の進行状況を示します。これは、サーバーがクライアントからより多くのデータを受信するたびに、最大で毎秒発行されます。オフセットプロパティは、その時点でサーバーに転送された合計バイト数に設定されます。

インプリ

apaheでCORSでcookieがやり取りできように設定[v2]

  • http.confにCORSでのcookieの設定(Access-Control-Allow-Credentials)を追加します。
  • この設定はクロスオリジンが発生していないので不要だと思います。
http.conf
<Directory /var/www/files>
    Header always set Access-Control-Allow-Origin "https://www.your-site.net"
    Header always set Access-Control-Allow-Credentials "true" 
</Directory>

htmlでCORSでcookieをやり取りできるようにする[v2]

  • tus-js-clientのデモのindex.htmlでtus.jsのoptionにwithCredentialを設定します。75行目あたりにあります。
  • この設定はクロスオリジンが発生していないので不要だと思います。[v2]
tus-js-cilent/demos/browser/demo.js
var options = {
        //
        // Cookie対応する
        withCredentials : true,
...

クライアントのブラウザにクッキーを書き込む

  • JavaScriptでクッキーを(例えばセッションID情報)を格納します。最終行に追加しておきます。
tus-js-cilent/demos/browser/demo.js
// クッキーのセット
document.cookie = 'ID_SESSION=c043fe31-cf1b-4c77-AAAA-7a49c49c14d5; path=/; secure;'

tusdでファイルフックできるようにする

  • 処理の段階でtusdhookできるようにtusdの起動を次のようにしました。
run_tusd.bash
$ cat $(which run_tusd.bash)
#!/bin/bash -vxeu
# tusdをオプション込みで起動する
# log file
exec &> /var/www/log/$(basename $0).$(date '+%y%m%d_%H%M%S').$$.bash
#
# https用コマンドライン
sudo -u apache /usr/local/bin/tusd -upload-dir /var/www/files/ -behind-proxy -hooks-dir /var/www/hooks -verbose &
  • tusdのフックはオプション-hooks-dirでディレクトリを指定することでファイルフックが可能になります。このディレクトリにpre-createとかの名前のshell scriptを書いておけばいいです。

tusdのファイルアップロード開始時にクッキーを取り出す

  • ファイルアップロード開始時はpre-createをキックするので、これにクッキー処理を書いておきます。下記の例は設定したキッキーのセッションIDを読み出します。
  • 実験用なのでどういった起動時の環境変数もモニターします。
$ cat pre-create
#!/bin/bash -xveu
exec 2> /var/www/log/$(basename $0).$(date '+%y%m%d_%H%M%S').$$.bash
CMD_SESSION=$( basename $0 )
___TUS___=$( cat - |jq )
___ENV___=$( printenv | sort )
  • コード解説します。
    • tusd-hooks-dir /var/www/hooksで指定したディレクトリのpre-createという名前のコマンドを起動します。
    • ここではbashで起動します。
    • logを取っておきます
    • 起動されたコマンド名を変数CMD_SESSIONに設定されます。
    • tusdは起動するフックにstdinとして変数を格納します。そのため読み出しをcat -で読み出し、jqで可読性をあげ、変数___TUS___に入れておきます
    • ついでにどんなSHELL環境変数だったのかを変数___ENV___に入れておきます。
    • tusdからキックされたpre-createのクッキーがどうだったのか、logファイルを確認しましょう。

確認(pre-createに渡された変数)

  • それではlogを確認しましょう。全行のせます。セキュリティの観点で省略している部分やサイト名、IPは変更しています。 ログファイルです。
/var/www/log/pre-create.200628_084337.14802.bash
$ cat pre-create.200628_084337.14802.bash 
CMD_SESSION=$( basename $0 )
++ basename /var/www/hooks/pre-create
+ CMD_SESSION=pre-create
___TUS___=$( cat - |jq )
++ cat -
++ jq
+ ___TUS___='{
  "Upload": {
    "ID": "",
    "Size": 37091,
    "SizeIsDeferred": false,
    "Offset": 0,
    "MetaData": {
      "filename": "your-upload-music-file.mp3"
    },
    "IsPartial": false,
    "IsFinal": false,
    "PartialUploads": null,
    "Storage": null
  },
  "HTTPRequest": {
    "Method": "POST",
    "URI": "/files/",
    "RemoteAddr": "[::1]:57482",
    "Header": {
      "Accept": [
        "*/*"
      ],
      "Accept-Encoding": [
        "gzip, deflate, br"
      ],
      "Accept-Language": [
        "ja,en-US;q=0.7,en;q=0.3"
      ],
      "Connection": [
        "Keep-Alive"
      ],
      "Content-Length": [
        "0"
      ],
      "Cookie": [
        "ID_SESSION=c043fe31-cf1b-4c77-AAAA-7a49c49c14d5"
      ],
      "Origin": [
        "https://www.your-site..net"
      ],
      "Referer": [
        "https://www.your-site.net/vendors/node_modules/tus-js-client/demos/browser/index.html"
      ],
      "Tus-Resumable": [
        "1.0.0"
      ],
      "Upload-Length": [
        "37091"
      ],
      "Upload-Metadata": [
        "filename My4xLjItaHR0cHPjgYvjgpnjgrvjgq3jg6Xjg6rjg4bjgqPjgabjgpnkv53orbfjgZXjgozjgZ/mjqXntprjgpLnorrnq4vjgabjgpnjgY3jgarjgYTjgajoqIDjgo/jgozjgZ/jgajjgY3jga7lr77lh6bms5UubWQ=,filetype"
      ],
      "User-Agent": [
        "Mozilla/5.0 (省略)
      ],
      "X-Forwarded-For": [
        "(省略)"
      ],
      "X-Forwarded-Host": [
        "www.your-site.net"
      ],
      "X-Forwarded-Proto": [
        "https"
      ],
      "X-Forwarded-Server": [
        "www.your-site.net"
      ]
    }
  }
}'
___env___=$( printenv | sort )
++ printenv
++ sort
+ ___env___='HISTSIZE=1000
HOME=/usr/share/httpd
HOSTNAME=(省略)
LANG=ja_JP.UTF-8
LOGNAME=apache
LS_COLORS=(省略)
MAIL=(省略)
PATH=(省略)
PWD=/var/www/hooks
SHELL=/sbin/nologin
SHLVL=1
SUDO_COMMAND=/usr/local/bin/tusd -upload-dir /var/www/files/ -behind-proxy -hooks-dir /var/www/hooks -verbose
SUDO_GID=0
SUDO_UID=0
SUDO_USER=root
TERM=xterm-256color
TUS_ID=
TUS_OFFSET=0
TUS_SIZE=37091
USER=apache
USERNAME=apache
XDG_SESSION_ID=355
_=/bin/printenv'

設定したcookie値を、きちんとpre-createで読むことができていますね。これはstdinからの情報にあります。このコマンドを起動した環境変数には(もちろん)cookie情報がないことも確認できました。これでセッション情報に基づいたユーザ毎の処理をLATSでもできそうです。uppyにもCredentialの設定はできますよ。[v2]

どなたかのお役に立てましたらとても嬉しいです。今回の記事は”動いたよ”という段階なので間違った設定や使い方があるかもしれません。その時はご指摘ください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0