てくてく

2023年5月2件]

お久しぶりの更新です!
最近少し忙しかったりイーガ団の相手をしていたりで滞ってしまいました。
良くも悪くも気楽にやれてる証かな?と楽観的に考えてます。
義務感でやると長続きしなくなってしまいますからね……(経験談です)

さて、GitHubActionsでWebサイトの更新を自動化したいっ!で当サイトもお世話になっているWitchServerのやり方は分かり次第、と載せていました。
やり方がわかったのはだいぶ前なのですがWitchServerさんで簡単てがろぐインストールができるようになったので、これに乗じて記事にしました。


WitchServerの対応に対応するてがろぐ制作者にしし様もやはりつよい……
それではさっそくやり方をご紹介しますっ!

今回の環境
・Windows10
・GitHub
・Sourcetree
・WitchServer

Actions secrets
暗号化の設定の仕方は前回を御覧ください。
設定する暗号化は以下の通りです。

①FTPサーバー
Name:FTP_SERVER
Secret:提供ドメイン
([契約時決めたもの].witchserver.netあるいは[契約時決めたもの].witchserver.net)
こちらの情報はコントロールパネルのご契約情報から確認できます。
20230521160224-admin.png

②FTPユーザー名
Name:FTP_USERNAME
Secret:FTPユーザー名

③FTPパスワード
Name:FTP_PASSWORD
Secret:FTPパスワード

FTPユーザーの追加はコントロールパネル「FTP設定」で追加できます。
デフォルトでは追加されていなかったはずなので、設定しておきましょう。
複数ユーザーを追加した場合、②と③は一致しなければ接続できないので注意が必要です。

yml
ここが一番の肝ですね!
WitchServerさんはFTPS通信のみ対応しているので、FTP Deployを利用したymlの記述方法も変わってきます。

まずは全文お見せします。
on: push
name: Deploy website on push
jobs:
  web-deploy:
      name: Deploy
      runs-on: ubuntu-latest
      steps:
      - name: Get latest code
        uses: actions/checkout@v3

      - name: Sync files
        uses: SamKirkland/FTP-Deploy-Action@v4.3.4
        with:
          server: ${{ secrets.FTP_SERVER }}
          username: ${{ secrets.FTP_USERNAME }}
          password: ${{ secrets.FTP_PASSWORD }}
          protocol: ftps
          server-dir: サーバーディレクトリ
          local-dir: ローカルディレクトリ


中身を見ていきます。
on: push
これは前回記述した
on:
  push:
    branches:
      - main

と同じ意味です。
前回は「mainブランチがプッシュされたら」とブランチを分けて使う場合を考えての記述でした。
もし別のブランチを利用している場合は、前回と同じ記述にします。
今回のこの記述は「すべてのプッシュに対して」動作します。
別途ブランチ設けていない場合は、一行で済みますということでご紹介しました。

- name: Get latest code
  uses: actions/checkout@v3

前回はv2を使用しました。FTP Deployはどうやら4.3.3以降を使う場合、v3を使わないと動作しないようです(参考:Deploy error on actions/checkout@v2)。
なので最新バージョン(2023/04/03現在)を利用します。

- name: Sync files
  uses: SamKirkland/FTP-Deploy-Action@v4.3.4

最新バージョンを利用しないとエラーを吐かれデプロイできません(4.3.3は未確認なのでわかりませんが…)。なので最新バージョンを利用します。
前回は@4.3.2の利用でした。今回のバージョンは@v4.3.4と「v」が入ってるのでお忘れないよう。
vを抜くと動作しません。

with:
    server: ${{ secrets.FTP_SERVER }}
    username: ${{ secrets.FTP_USERNAME }}
    password: ${{ secrets.FTP_PASSWORD }}
    protocol: ftps
    server-dir: サーバーディレクトリ
    local-dir: ローカルディレクトリ

server、username、passwordは前回と同じ記述です。
重要なのはprotocol: ftpsです。
FTP DeployはデフォルトがFTP通信なので、FTPS通信だと明示します。
これがないとWitchServerへはデプロイできません。必ず記述しましょう。

server-dirは/public_html/アップしたいディレクトリ名/を入れます。
コントロールパネルのドメイン設定から、デプロイしたいドメインのパスを記述してください。
local-dirは前回と同じで、設定しない場合はroot以下が対象です。

GitHub管理したいけどサーバー同期はしないファイルやフォルダがある場合は、excludeを記述します。そのあたりは前回記事にありますのでそちらをご覧ください。

上記ymlでWitchServerへデプロイできるかと思います。

注意点
0バイトファイルはActionsでアップロードしない
原因はわからないのですが、0バイトのファイルをあげるとエラーになります。
もし0バイトのファイルが入ったものをデプロイしようとすると、中途半端なデプロイになりサーバーに上がったファイルと上がらないファイルが発生します。
GitHubからActionsを確認すると以下のようなエラーが発生します。
Error: 139787667785600:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:308:
 (control socket) {
  library: 'SSL routines',
  function: 'ssl3_get_record',
  reason: 'wrong version number',
  code: 'ERR_SSL_WRONGVer 4.0.0NUMBER'
}
Error: Error: 139787667785600:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:308:
 (control socket)

こちらのIssueで「0バイトファイルのせいだったみたい!OpenSSLのバグかも?」とコメントがあったので0バイトファイルを除外したら無事デプロイできました。ただ本当にOpenSSLのバグかどうかは不明です。
なお、GitHubにあげるだけなら大丈夫だと思うのでymlにexcludeを追記し0バイトファイルをアップロードしないやり方も使えると思います。

「0バイトファイルって空っぽじゃん。そもそもあげなくない?」と思うでしょう。
配布プログラムなどを利用している方は、ディレクトリ内に0バイトファイルがある可能性があります。
私の場合は、do様配布のいいねボタン改を利用しており、その中に0バイトファイルがあったことから発生したエラーでした。
いいねボタン改を利用している方は、いいねぼたん改フォルダ内のdatas > setting > deny.datはFTPツールで別途サーバーへアップロードしたほうが良いかと思います。
FTP DeployはこのActionsを使ってアップロードしたものを管理しているので、FTPツールで別途アップロードしたファイルは対象外になります。
いいねボタン改の中身をいじっていなければ、いっそこちらのファイルまるまるGitHubではなくFTPツールで管理したほうが楽かもしれないですね。
一度設置すればあとはアップデート以外触ることはほぼ無いと思うので、GitHub管理の対象にしなくても良さそうと個人的には思います。

たまに失敗する
エラー文章を残してないので申し訳ないのですが、たまにデプロイに失敗します。
毎回ではないのですが、CORESERVERやリトルサーバーは失敗したことないので比較するとたまに程度ではありますが失敗します。
その場合はGitHubのActionsから手動で再度実行すると成功します。
今後エラーが分かり次第こちらに記載します。

デプロイできるようになるまでに発生したエラー
下記のエラーは①protocolをftpsに指定 ②最新バージョン利用で解決したものです。
なのであまり参考にはならないかも知れませんが、自分のためにも載せておきます。
ちなみに失敗しまくってるのがこの画像からわかります。
何かと失敗しまくった残骸
何かと失敗しまくった残骸

テストで別ドメインで試したりもしたので画像のがすべてではないのですが、まあまあ苦戦しました。

エラー① protocol未指定
FTPError: 530 Non-anonymous sessions must use encryption.
    at FTPContext._onControlSocketData (/home/runner/work/_actions/SamKirkland/FTP-Deploy-Action/4.3.2/dist/index.js:5254:39)
    at Socket.<anonymous> (/home/runner/work/_actions/SamKirkland/FTP-Deploy-Action/4.3.2/dist/index.js:5095:44)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:268:11)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23) {
  code: 530
}
Error: FTPError: 530 Non-anonymous sessions must use encryption.

FTPが暗号化していない仕組みなこともあり「暗号化せい」というようなことを言われてます。
protocolをFTPSにしたらこのエラーは消えました。
※前回記事のymlでやって失敗してます。

エラー② タイムアウト
Error: Timeout (control socket)
    at Socket.<anonymous> (/home/runner/work/_actions/SamKirkland/FTP-Deploy-Action/4.3.2/dist/index.js:5288:58)
    at Object.onceWrapper (events.js:420:28)
    at Socket.emit (events.js:314:20)
    at Socket._onTimeout (net.js:483:8)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)
Error: Error: Timeout (control socket)

protocolにFTPSを追加して試したもの。初動だと全データアップロードするのでどうしても時間はかかってしまうが、タイムアウトするほどの量ではない。が、タイムアウトと言われたからには時間がかかりすぎていたのかも知れない…。
この時点ではcheckoutはv2、FTP Deployは4.3.2でやってます。
最新バージョンにしたらタイムアウトしなくなりこのエラーも出なくなりました。
最新バージョンは未指定だと30000ミリ秒=30秒でタイムアウトします。なので過去バージョンはもっと短かったか、サーバー側から切られたからのどちらかが原因かなと考えてます。

エラー③ ネットワークストリームの読み取りに失敗
FTPError: 426 Failure reading network stream.
    at FTPContext._onControlSocketData (/home/runner/work/_actions/SamKirkland/FTP-Deploy-Action/4.3.2/dist/index.js:5254:39)
    at TLSSocket.<anonymous> (/home/runner/work/_actions/SamKirkland/FTP-Deploy-Action/4.3.2/dist/index.js:5095:44)
    at TLSSocket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:268:11)
    at TLSSocket.Readable.push (_stream_readable.js:213:10)
    at TLSWrap.onStreamRead (internal/stream_base_commons.js:188:23) {
  code: 426
}
Error: FTPError: 426 Failure reading network stream.

これがとてつもなく苦労した。
同じ問題を抱えたIssueで「このエラーは特定のホスティングサービス(サーバーのことだと思われる)で発生するみたい」のコメントや、vsftpd(FTPの相手をしてくれるサーバー側のプログラム)で同じ問題が起こるコメントもあり、さらにvsftpdを調べていくとvsftpdでSSL/TLS(暗号化技術の1つ。FTPSのSの意味がこれ)を利用するには設定が必要で~~とかApacheの設定をいじると使える~~~とか……
要するに、サーバー側の設定の問題でこちらではどうしようもないこと、なのだろうと解釈してます。
ただ、FTP Deployのバージョンを最新バージョン(4.3.4)にしたらこのエラー出なくなりました。
サーバーサイドは未履修なので結局の原因は分からずじまいなのがもやもやするものの、ひとまず動いたのでよしとします。

最後に

些細な独り言を拾ってくださる、まさに「サポートの手厚い」サーバーさんです。
ちなみにツイートの件は上記エラー③のことで解消されたと報告済みです。その後のレスもありご丁寧に対応していただきありがたい限りです。
冒頭でお伝えしたてがろぐについてもそうですが、最近技術ブログを開始されました。

こちらの記事の中をみたところ、色んなサイトでお見かけする「phpを使うと共通部分楽に管理できるよ!」と言った内容だけでなくSSIやJavaScript、jQueryでのやり方まで載せてくださっています。
ローカルでphpの確認が難しい環境でのサイト運営の場合、JavaScriptやjQueryでのやり方が分かればとても助かりますよね!
こうした側面からもWitchServerさんは個人サイト運営者に寄り添ってくれる素晴らしいサーバーさんですので、ぜひおすすめします。

関連記事
GitHubActionsでWebサイトの更新を自動化したいっ!

参考・リンクまとめ
※敬称略
WitchServer
WitchServer てがろぐ設置マニュアル
魔導書と杖 WitchServer公式技術ブログ
てがろぐ WitchServerでのセットアップ手順
FTP Deploy
Deploy error on actions/checkout@v2
FTP Deploy checkoutバージョンエラー
FTP Deploy 0バイトエラーIssue
FTP Deploy ネットワークストリーム読み込みエラーのIssue
do
いいねボタン改
.htaccessやサーバー設定でBasic認証ができるわけですが、ブラウザからIDやパスワードを求められるとちょっとびっくりします。
昔そういう個人サイトを見たことがあるのですが、フォレストやnanoなどの認証ばかり触れていたせいでブラウザからの認証に「なんだこれ!怖い!」と避けていた記憶が蘇ります。
サイトを運営する立場になった今ならあれはそこまで恐れるものでもないとわかるのですが、せっかくならログイン周りもデザインしたいところ・・・
個人サイトで入り用だったのもあり、JavaScriptで簡単なログイン認証を自作してみました!
今回はログインに焦点を絞りましたが、流用すればログインに限らないパスワード認証にも使えると思います。

デモ
こちらのデモページから動作確認ができます。
仕様
①indexページでパスワード認証
成功:コンテンツページへ飛ぶ
失敗:「パスワードが違います」と表示

②ログインに成功したら、次回以降パスワードは自動入力
 今回はパスワード保存の期限を設定していないので、使用したライブラリのデフォルト期間(365日)はCookieで保存されます。

③ログインしていない状態でindex以外のページへいったら、内容を隠してログイン画面をポップアップ表示
成功:ポップアップが消えて中身が見える
失敗:画面はそのまま「パスワードが違います」と表示される

④ログインしていればindex以外のページへ直接いってもログイン画面が出ず中身を見れる

⑤コードからパスワードが読まれないようハッシュ化
暗号化:暗号化されたデータを元のデータに戻せるタイプ
ハッシュ化:暗号化されたデータは元のデータに戻せない

こんな感じですね。
こちらの作り方を解説していきます~

準備
  • jQuery…jquery-cookieのために必要です
  • jquery-cookie…jQuery用いたCookie操作用
  • jsSHA…パスワードのハッシュ化用

ハッシュ化はjsSHAを使います。
「Newest Release / Download」のGitHubにリンクがあるので、そこからDLページへ飛びます。
Source code(zip)かSource code(tar.gz)のどちらかを選んでDLしてください。
いろいろなファイルが入っていますが、必要なのは「jsSHA-3.3.0/jsSHA-3.3.0/dist」にあるsha256.jsファイルだけです。

ファイル構成
index.html
contents.html
css/style.css
js/
├login.js
└3rd/sha256.js
さきほどDLしたsha256.jsをこの位置に入れます。
自分が作ったものと区別できるよう3rdフォルダに入れていますが、パスが通っていればどこでもOKです。
login.jsにログインの処理を書いていきます。

JavaScriptの読み込み
まずJavaScript周りの読み込みしておきましょう。
ログイン認証したいページやログインしていなければ中を見せたくないページに各種読み込んでいきます。
今回だとindex.htmlとcontents.htmlですね。
htmlファイルのbodyの閉じタグ直前に下記を記述します。
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.6.4.min.js" integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8=" crossorigin="anonymous"></script>
<!-- 3rd -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.js"></script>
<script src="js/3rd/sha256.js"></script>
<!-- script -->
<script src="js/login.js"></script>

jQueryのCDNはこちらをコピペしてます。
今回はjQuery Core 3.6.4 minifiedを使いました。
配布プログラムを利用していてjQueryを入れてるよ!ということであればそちらを使うのが良いかと。

jquery-cookieのCDNはこちらの最新版を使ってます。
今回はVersion1.4.1を使いました。URLが2つありますが下の方を使ってます(どちらでも大丈夫です)。

sha256.jsは準備項目でDLしたファイルです。
login.jsはログイン周りの処理を書くファイルです。

index.html
ログイン周りに必要な部分だけ抜粋します。
<div id="loginResult">パスワードが違います</div>
<div>
    <input type="password" placeholder="password" id="loginPass">
    <input type="button" value="送信" id="login">
</div>

loginResultにはパスワードが異なるときの文章を記述します。
inputdivタグで囲っていますが、これはformにするとエンターキーでsubmitになってしまうことからdivにしてます。そのあたりの処理(エンターキーで認証処理を実行)を書けるようであればformでもOKかと!

そしてパスワードを入力するのが
<input type="password" placeholder="password" id="loginPass">
の部分です。type="password"で伏せ字にしてますがtype="text"でもOK。

パスワード認証の処理は
<input type="button" value="送信" id="login">
のクリックで実行するようにします。

contents.html
今回はわかりやすいようにcontents.htmlの名前になっていますが、ログインしないと見れないファイルに記述する内容です。
まずログインするまでぼかしておきたいタグにclass="passcheck"というクラスを追加します。
bodyに追加するとログイン用のポップアップもぼかしてしまうのでbodyに入れないようにします。
例えば
<body>
    <header class="passcheck">
        <!-- ヘッダーの記述 -->
    </header>

    <main class="passcheck">
        <!-- ここにコンテンツの記述 -->
    </main>
    
    <footer class="passcheck">
       <!-- ここにフッターの記述 -->
    </footer>

    <!-- 各種scriptの読み込み(省略) -->
</body>

といった感じです。
ぼかさなくていいなってものがあればクラスを外してください。

次にログイン用のポップアップを記述します。
<div class="overlay">
    <div class="popup-window">
        <h2>Login</h2>
        <div>
            <div id="loginResult">パスワードが違います</div>
            <div>
                <input type="password" placeholder="password" id="loginPass">
                <input type="button" value="送信" id="login">
            </div>
            <a href="index.html">indexへ</a>
        </div>
    </div>
</div>

index.htmlへ戻るリンクはindexページへ戻れるように貼ってます。不要なら削除してOK。
必ずpasscheckの外側に記述してください
demoだと下記のようにmainタグとfooterタグの間に記述してます。
<main class="passcheck">
    <!-- ここにコンテンツの記述 -->
</main>

<!-- ログイン用ポップアップ -->
<div class="overlay">
    <div class="popup-window">
        <h2>Login</h2>
        <div>
            <div id="loginResult">パスワードが違います</div>
            <div>
                <input type="password" placeholder="password" id="loginPass">
                <input type="button" value="送信" id="login">
            </div>
            <a href="index.html">indexへ</a>
        </div>
    </div>
</div>

<footer class="passcheck">
    <!-- ここにフッターの記述 -->
</footer>


css
#loginResult#loginResult.error.overlay.popup-windowを記述していきます。

ログイン失敗表示
#loginResult{
    display: none;
    /* 下記はデザイン用 */
    padding: 10px;
    margin: 10px auto;
    width: 80%;
    border: 1px solid transparent;
}

#loginResult.error{
    display: block;
    /* 下記はデザイン用 */
    border-color: #de9a9a;
    background: rgba(222, 154, 154, 0.25);
}

デフォルトは非表示で、errorクラスを追加したら表示するようにします。

ポップアップ
.overlay {
    display: none;
    position: fixed;
    z-index: 9999;
    width: 100%;
    height: 100vh;
    top: 0;
    left: 0;
    background: rgba(0, 0, 0, .5)
}

.popup-window{
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    /* 下記はデザイン用 */
    width: 90vw;
    max-width: 380px;
    padding: 20px 0;
    background: #3a3a3a;
}

デフォルトは非表示です。表示処理をJavaScriptで行います。

そしてぼかし用のクラスです。
.blur {
    filter: blur(10px);
}


login.js
ここが要ですね!
まずスクリプトを書いていく前にパスワードを用意します。
SHA256に変換してくれるサイトでSHA256変換したパスワードを用意します。
わかりやすさからこちらのサイトで用意しました。出力形式は小文字です。
今回使うライブラリのjsSHAページにあるデモを使ってもいいでしょう。
その場合はHasing Demoの欄に以下の設定で出力します。
Input Text: パスワードにしたい文字列を入力
Input Type: TEXT
SHA Variant: SHA-256
Number of 1
Rounds: Output Type: HEX
Output Hashに出力された文字列がハッシュ化されたパスワードです。

login.jsに記述するコード全文はこちらです。
$(function(){
    const PASS_HASH = 'さきほど出力したハッシュ化されたパスワード';

    /* index.htmlでない且つCookieのハッシュ化パスワードが異なっていたら
       passcheckクラスにぼかしをつける+ポップアップを表示 */
    if(!location.pathname.includes('index.html') && $.cookie('loginhash') != PASS_HASH){
        $('.passcheck').addClass('blur');
        $('.overlay').show();
    }
    
    /* Cookieにログインパスワードが残っていたら自動入力 */
    $('#loginPass').val($.cookie('loginpass'));

    /* ログインボタンをクリックしたら認証処理 */
    $('#login').click(function() {
        const pass = $('#loginPass').val();
        const shaObj = new jsSHA('SHA-256','TEXT');
        shaObj.update(pass);
        const hash = shaObj.getHash('HEX');
        if (PASS_HASH === hash) {
            /* 入力されたパスワードが合っていたら、Cookieに保存 */
            $.cookie('loginpass',pass);
            $.cookie('loginhash',hash);
            if(location.pathname.includes('index.html')){
                /* index.htmlにいたらコンテンツページへ飛ぶ */
                window.location.href = 'contents.html';
            }else{
                /* index.htmlでなければ、ぼかしを消してポップアップを非表示 */
                $('.passcheck').removeClass('blur');
                $('.overlay').hide();
            }
        }else{
            /* パスワードが不一致なら「パスワードが違います」のエラー表示 */
            $('#loginResult').addClass('error');
        }
    });
})

.htaccessで拡張子を表示しない設定をしている場合location.pathname.includes('index.html')の拡張子も消してください。
セキュリティ的にはまだまだかと思いますが、パッと見でパスワードがわからないくらいにはなってるかなと思います。
もっとしっかりやるならパスワード管理用のファイルを用意したほうがいいのですが、そこまでガチガチじゃないくていいかなというのと、ファイル読み込みなどの処理が面倒だったので省きました。

最後に
phpで作ってみようかな~と思ったのですが、ちょっとまだ勉強不足で時間がかかりそうだったのでJavaScriptで作りました。
ゆくゆくはきちんと中身が見られないようパスワード用のファイルを用意したり、パスワードの設定そのものをできるようにしたいところ・・・
とりあえずなものではあるものの、割と悪くないんじゃないかな?と個人的に思ってます。
上手く出来ると楽しい~~!

参考
【超シンプル】ポップアップをHTMLとCSSだけで実装する

DASHBOARD

つぶやき

アカウント作成しました!
Twitter(現X)

全文検索

カレンダー

日付一覧を表示
2023年5月
123456
78910111213
14151617181920
21222324252627
28293031

Thanks !

Link

Contact

目次