<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[ゆるっとエンジニアブログ]]></title><description><![CDATA[No Description]]></description><link>https://jikoblog.netlify.app/</link><image><url>https://jikoblog.netlify.app/favicon.png</url><title>ゆるっとエンジニアブログ</title><link>https://jikoblog.netlify.app/</link></image><generator>Ghost 2.9</generator><lastBuildDate>Mon, 18 Sep 2023 00:15:13 GMT</lastBuildDate><atom:link href="https://jikoblog.netlify.app/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Box CLI でページ割りを使用する]]></title><description><![CDATA[Box CLI では、listコマンド(例: box users:listなど、:list部分は省略可)を使用することでオブジェクト(ユーザーなど)の一覧を取得することができますが、上限が1000となっており、またページ割り機能も未実装のようなので(執筆時点)、1000件を超える場合は全部のデータが取得できないようです(関連Issue)。 そこで、listコマンドを使用せずにbox requestコマンドでページ割りを行って1000件以上ある場合でも、全部のデータを取得するスクリプトを作成しました。内容を以下に記載します。 利用環境 以下の環境を使用しました * Box CLI: ver 3.1.0(バージョン依存しないと思いますが、一応記載) * OS: Windows 10 * Powershell: 5.1.19041.3031 MacOSおよびLinuxでも、pwshをインストールすることで利用できるはずです。 Ref: https://ja.developer.box.com/guides/cli/quick-start/powershell-sc]]></description><link>https://jikoblog.netlify.app/get-trashed-items-with-marker-pageination-using-boxcli/</link><guid isPermaLink="false">Ghost__Post__65075b878ed63100015115fb</guid><category><![CDATA[Box]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Sun, 17 Sep 2023 23:53:57 GMT</pubDate><media:content url="http://localhost:2368/content/images/2023/09/BoxCLI.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="http://localhost:2368/content/images/2023/09/BoxCLI.png" alt="Box CLI でページ割りを使用する"/><p>Box CLI では、<code>list</code>コマンド(例: <code>box users:list</code>など、<code>:list</code>部分は省略可)を使用することでオブジェクト(ユーザーなど)の一覧を取得することができますが、上限が<a href="https://github.com/box/boxcli/blob/955106ffa5d7938c567e5440868f2ec3c87045ce/src/pagination-utils.js#L5">1000</a>となっており、またページ割り機能も未実装のようなので(執筆時点)、1000件を超える場合は全部のデータが取得できないようです(<a href="https://github.com/box/boxcli/issues/220">関連Issue</a>)。<br> そこで、<code>list</code>コマンドを使用せずに<code>box request</code>コマンドでページ割りを行って1000件以上ある場合でも、全部のデータを取得するスクリプトを作成しました。内容を以下に記載します。</br></p> <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="%E5%88%A9%E7%94%A8%E7%92%B0%E5%A2%83">利用環境</h1> <p>以下の環境を使用しました</p> <ul> <li>Box CLI: ver 3.1.0(バージョン依存しないと思いますが、一応記載)</li> <li>OS: Windows 10</li> <li>Powershell: 5.1.19041.3031</li> </ul> <p>MacOSおよびLinuxでも、<code>pwsh</code>をインストールすることで利用できるはずです。<br> Ref: <a href="https://ja.developer.box.com/guides/cli/quick-start/powershell-script-templates/#%E5%89%8D%E6%8F%90%E6%9D%A1%E4%BB%B6">https://ja.developer.box.com/guides/cli/quick-start/powershell-script-templates/#前提条件</a></br></p> <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="%E5%AE%8C%E6%88%90%E7%B3%BB">完成系</h1> <p>いきなり完成系から記載しちゃいます。以下の例は、Boxのゴミ箱のアイテム全件を<a href="https://ja.developer.box.com/guides/api-calls/pagination/marker-based/">マーカーベースのページ割り</a>を使用して取得しCSVに出力するスクリプトになります(ゴミ箱のアイテムってすぐ多くなってウェブアプリで見るのが大変ですよね)。</p> <pre><code class="language-powershell"># 0. Save the current encoding and switch to UTF-8. (Ref: https://stackoverflow.com/questions/58438095/powershell-string-variable-with-utf-8-encoding#answer-58438716) $prev = [Console]::OutputEncoding [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new() # 1. Get 1st page via marker-based pagination $raw_data = box request /folders/trash/items --query="""usemarker=true&limit=100""" --fields=body.entries,body.next_marker --json # 2. Convert JSON string to JSON $json = $raw_data | ConvertFrom-Json # 3. Convert JSON to CSV and write it to output.csv $json.body.entries | Export-Csv -NoTypeInformation -Path .\output.csv -Encoding utf8 $cnt = 0 while( $json.body.next_marker ) { # 4. Build the query parameter for the next page $next_query = "usemarker=true&limit=100&marker=" + $json.body.next_marker # 5. Get 2nd page via marker-based pagination $next_data = box request /folders/trash/items --query="""$next_query""" --fields=body.entries,body.next_marker --json # 6. Convert JSON string to JSON $json = $next_data | ConvertFrom-Json # 7. Append the data for 2nd page to output.csv $json.body.entries | Export-Csv -Path .\output.csv -Append -Encoding utf8 # 8. Repeat step #4 to step #7 until you reach the last page (aka next_marker is null). $cnt++ "Page $cnt, next_marker: " + $json.body.next_marker } # Restore the previous encoding. [Console]::OutputEncoding = $prev </code></pre> <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="%E8%A7%A3%E8%AA%AC">解説</h1> <p>コメントをちょこちょこ入れておりますが、一応各行の処理内容について記載します。</p> <h3 id="%E3%82%B9%E3%83%86%E3%83%83%E3%83%971">ステップ1</h3> <ul> <li>BoxCLIには<a href="https://github.com/box/boxcli/blob/main/docs/trash.md#box-trash-1"><code>box trash</code></a>(もしくは<code>box trash:list</code>)というコマンドレットがありますが、前述の通りこちらはページ割りに対応しておらず、1000件以上のアイテムを取得することができません。</li> <li>そこで、<a href="https://github.com/box/boxcli/blob/main/docs/request.md"><code>box request</code></a>という任意のURLやパラメータを指定できるコマンドレットを使用して、<a href="https://ja.developer.box.com/guides/api-calls/pagination/marker-based/">マーカーベースのページ割り</a>のパラメータである<code>usemarker=true</code>をCLIへと渡します。</li> <li>なお、<code>box request</code>を使用すると、以下のようにステータスコードやレスポンスヘッダーなど不要な情報も含まれます。</li> </ul> <pre><code>PS C:\Users\kojimaru> box request /folders/trash/items --query="""usemarker=true&limit=100""" Status Code: 200 Headers: Date: 'Sun, 17 Sep 2023 22:47:32 GMT' Content-type: application/json Transfer-encoding: chunked X-envoy-upstream-service-time: '364' Box-request-id: 185e9224815c2641f06cad53eeb33f71 Cache-control: 'no-cache, no-store' Strict-transport-security: max-age=31536000 Via: 1.1 google Alt-svc: 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000' Body: Entries: - Type: folder ID: '85557482328' Sequence ID: '1' ETag: '1' Name: '26061' Limit: 1 Next Marker: >- eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNORGd5TXpJNGZRIn0 </code></pre> <p>ので、<code>--fields=body.entries,body.next_marker</code>で必要なフィールドのみが出力されるように指定します。また、<code>--json</code>でJSON形式になるように指定します</p> <pre><code>PS C:\Users\kojimaru> box request /folders/trash/items --query="""usemarker=true&limit=100""" --fields=body.entries,body.next_marker --json { "body": { "entries": [ { "type": "folder", "id": "85557482328", "sequence_id": "1", "etag": "1", "name": "26061" } ], "next_marker": "eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNORGd5TXpJNGZRIn0" } } </code></pre> <p>※ちなみに</p> <h3 id="%E3%82%B9%E3%83%86%E3%83%83%E3%83%972">ステップ2</h3> <ul> <li>ステップ1で取得したデータはJSON形式に成形されてますが、データ型としては文字列なので<a href="https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/convertfrom-json?view=powershell-7.3"><code>ConvertFrom-Json</code></a>でJSONオブジェクトに変換します。</li> </ul> <h3 id="%E3%82%B9%E3%83%86%E3%83%83%E3%83%973">ステップ3</h3> <ul> <li>JSONオブジェクトの要素である<code>body.entries</code>の内容(最初のページの100件)を<a href="https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/export-csv?view=powershell-7.3"><code>Export-Csv</code></a>でCSVファイルへと書き出します。</li> <li><code>-Encoding utf8</code>を指定することでBOM付きのCSVとして出力します(Excelで開く際の文字化け防止)。</li> <li><code>-NoTypeInformation</code>を指定することでカラムヘッダーの上の行に挿入される不要な行(#TYPE情報ヘッダー)を削除します。</li> </ul> <h3 id="%E3%82%B9%E3%83%86%E3%83%83%E3%83%974">ステップ4</h3> <ul> <li><code>body.next_marker</code>が存在する場合(次のページが存在する場合)は、そのmarkerを使用して次のページを取得するためのクエリ文字列を生成します。</li> </ul> <h3 id="%E3%82%B9%E3%83%86%E3%83%83%E3%83%975%EF%BD%9E8">ステップ5~8</h3> <ul> <li>ステップ4のクエリ文字列を使用してリクエストを送信します。</li> <li>結果をJSONオブジェクトに変換し(ステップ2と同様)、それをCSVファイルに追記(<code>-Append</code>)します</li> <li><code>body.next_marker</code>が存在する場合(さらに次のページが存在する場合)は、そのmarkerを使用して次のページを取得するため、ステップ4~7を繰り返します。<code>body.next_marker</code>が存在しない場合はこれ以上のアイテムがない(最終ページに到達した)ということなので、ループから抜けて終了します。</li> </ul> <h3 id="%E3%82%B9%E3%83%86%E3%83%83%E3%83%970">ステップ0</h3> <ul> <li>ここまでの解説ではスルーしてましたが、この前処理は一体なんなのか?これは文字化け防止の処理になります。</li> <li>今回のスクリプトでは、Box CLI(外部プログラム)で取得した出力結果を変数に代入しているのですが、その際に<code>[Console]::OutputEncoding</code>で定義されたエンコード方式を使用してしまうようです。よって、今回の私の日本語OSのような環境だと、以下のようにshift-jisが使用されることでBox CLIの出力エンコード方式と一致せず、文字化けが起きているようでした。</li> </ul> <pre><code>PS C:\Users\kojimaru> [Console]::OutputEncoding BodyName : iso-2022-jp EncodingName : 日本語 (シフト JIS) HeaderName : iso-2022-jp WebName : shift_jis WindowsCodePage : 932 IsBrowserDisplay : True IsBrowserSave : True IsMailNewsDisplay : True IsMailNewsSave : True IsSingleByte : False EncoderFallback : System.Text.InternalEncoderBestFitFallback DecoderFallback : System.Text.InternalDecoderBestFitFallback IsReadOnly : True CodePage : 932 </code></pre> <ul> <li>よって、UTF-8を使用するように<code>[Console]::OutputEncoding]</code>に<code>[System.Text.UTF8Encoding]::new()</code>をセットすることで回避できました。</li> <li>ちなみに、最初の行で<code>$prev</code>に既存の出力エンコード方式を保存し、最終行で元の(<code>$prev</code>の)設定に戻してます。</li> <li>参考記事: <a href="https://stackoverflow.com/questions/58438095/powershell-string-variable-with-utf-8-encoding#answer-58438716">https://stackoverflow.com/questions/58438095/powershell-string-variable-with-utf-8-encoding#answer-58438716</a></li> </ul> <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="%E5%AE%9F%E8%A1%8C">実行</h1> <ul> <li>スクリプトの内容をコピーして「GetTrashedFolders.ps1」というファイル名に保存して、Powershellから実行してみます。</li> <li>すると以下のようにコンソール上にページ遷移の進捗が記録され、「output.csv:にもりもり各ページのアイテムが追記されていきます。</li> </ul> <pre><code>PS C:\Development\BoxCLI> .\GetTrashedFolders.ps1 Page 1, next_marker: eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNOVFE0TXpJNGZRIn0 Page 2, next_marker: eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNOVGcxTVRNeWZRIn0 Page 3, next_marker: eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNOakU0T1RZM2ZRIn0 Page 4, next_marker: eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNOalV4TlRJNGZRIn0 Page 5, next_marker: eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNOamcxT1RNeWZRIn0 Page 6, next_marker: eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNOekV5TnpJNGZRIn0 Page 7, next_marker: eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNOelF3TXpJNGZRIn0 Page 8, next_marker: eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNOelkyTnpJNGZRIn0 Page 9, next_marker: eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNOemt5TnpNeWZRIn0 Page 10, next_marker: eyJ0eXBlIjoiT3duZWRCeUZvbGRlciIsImRpciI6Im5leHQiLCJ0YWlsIjoiZXlKMmFXVjNVMk52Y0dVaU9pSmhiR3dpTENKc1lYTjBTV1FpT2pnMU5UVTNPREUzT1RNeWZRIn0 <snip> </code></pre> <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</h1> <ul> <li>今回の例ではBox APIで2種類あるページ割りのうち、<a href="https://ja.developer.box.com/guides/api-calls/pagination/marker-based/">マーカーベースのページ割り</a>を使用しましたが(こっちのほうがめんどくさそうだったので敢えて)、もう片方の<a href="https://ja.developer.box.com/guides/api-calls/pagination/offset-based/">オフセットベースのページ割り</a>も<code>box request</code>でパラメータとして<code>offset</code>の値を指定しインクリメントしながらページ遷移することで同様のことができると思います。</li> <li>また、ゴミ箱のアイテム取得を例にしましたが、他のリソース(ユーザーやコラボレーションなど)でも同様の処理が可能です。</li> <li>公式でもCLIを使用したPowershellのスクリプトをいくつか用意しているようなので、そちらも見てみるとおもしろいかも <a href="https://ja.developer.box.com/guides/cli/scripts/#powershell%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88">https://ja.developer.box.com/guides/cli/scripts/#powershellスクリプト</a></li> </ul> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[PostmanでBox APIを使ってみる (JWT認証)]]></title><description><![CDATA[PostmanでJWT認証方式を使用してBox APIを呼べるようにしてみました。 前置き Box APIでは複数の認証方式があり、公式ではOAuth 2.0を使用したPostmanコレクションが提供されています(手順はこちら)。 https://ja.developer.box.com/guides/tooling/postman/ ここでは、JWT認証を使用してPostmanからBox APIを呼ぶ方法について記載します。 Boxアプリケーションの作成・承認 Box APIを呼ぶにあたり、事前にBoxのカスタムアプリの作成と承認を行います。 1. まず、Boxの開発者コンソールからJWT認証方式のアプリを作成します。詳しい手順については、公式ページに記載があるのでこちらでは割愛します。 2. Box管理者としてログインし、#1で作成したアプリの承認を行います。こちらも公式ページに手順があるので割愛します。 なお、#1でアプリを作成する際の「キーペアの生成」手順でダウンロードされる config.json(以下のような形式でJWTアプリの認証に必]]></description><link>https://jikoblog.netlify.app/postman-box-jwt/</link><guid isPermaLink="false">Ghost__Post__63f6aad483e9300001f54b63</guid><category><![CDATA[Box]]></category><category><![CDATA[Postman]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Thu, 23 Feb 2023 03:01:40 GMT</pubDate><media:content url="http://localhost:2368/content/images/2023/02/maxresdefault.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="http://localhost:2368/content/images/2023/02/maxresdefault.jpg" alt="PostmanでBox APIを使ってみる (JWT認証)"/><p>PostmanでJWT認証方式を使用してBox APIを呼べるようにしてみました。</p> <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="Intro">前置き</h1> <p>Box APIでは複数の<a href="https://ja.developer.box.com/guides/authentication/select/">認証方式</a>があり、公式では<a href="https://ja.developer.box.com/guides/authentication/select/#oauth-20">OAuth 2.0</a>を使用したPostmanコレクションが提供されています(手順は<a href="https://medium.com/box-developer-blog/postman%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A65%E5%88%86%E3%81%A7box-api%E3%82%92%E9%96%8B%E5%A7%8B%E3%81%99%E3%82%8B-afa119c941af">こちら</a>)。<br> <a href="https://ja.developer.box.com/guides/tooling/postman/">https://ja.developer.box.com/guides/tooling/postman/</a></br></p> <p>ここでは、<a href="https://ja.developer.box.com/guides/authentication/select/#jwt">JWT認証</a>を使用してPostmanからBox APIを呼ぶ方法について記載します。</p> <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="box%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E6%88%90%E3%83%BB%E6%89%BF%E8%AA%8D">Boxアプリケーションの作成・承認</h1> <p>Box APIを呼ぶにあたり、事前にBoxのカスタムアプリの作成と承認を行います。</p> <ol> <li>まず、Boxの<a href="https://app.box.com/developers/console">開発者コンソール</a>からJWT認証方式のアプリを作成します。詳しい手順については、<a href="https://ja.developer.box.com/guides/authentication/jwt/jwt-setup/#%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E4%BD%9C%E6%88%90%E6%89%8B%E9%A0%86">公式ページ</a>に記載があるのでこちらでは割愛します。</li> <li>Box管理者としてログインし、#1で作成したアプリの承認を行います。こちらも<a href="https://ja.developer.box.com/guides/authorization/custom-app-approval/">公式ページ</a>に手順があるので割愛します。</li> </ol> <p>なお、#1でアプリを作成する際の「<a href="https://ja.developer.box.com/guides/authentication/jwt/jwt-setup/#%E3%82%AD%E3%83%BC%E3%83%9A%E3%82%A2%E3%81%AE%E7%94%9F%E6%88%90-%E6%8E%A8%E5%A5%A8">キーペアの生成</a>」手順でダウンロードされる <a href="https://ja.developer.box.com/guides/authentication/jwt/without-sdk/#1-json%E6%A7%8B%E6%88%90%E3%82%92%E8%AA%AD%E3%81%BF%E5%8F%96%E3%82%8B">config.json</a>(以下のような形式でJWTアプリの認証に必要となる情報が含まれたファイル)は後述の手順で使用します。</p> <pre><code class="language-json">{ "boxAppSettings": { "clientID": "abc...123", "clientSecret": "def...234", "appAuth": { "publicKeyID": "abcd1234", "privateKey": "-----BEGIN ENCRYPTED PRIVATE KEY-----\n....\n-----END ENCRYPTED PRIVATE KEY-----\n", "passphrase": "ghi...345" } }, "enterpriseID": "1234567" } </code></pre> <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="postman%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%83%BB%E8%A8%AD%E5%AE%9A">Postmanのインストール・設定</h1> <ol> <li>Postmanを<a href="https://www.postman.com/downloads/">公式</a>よりダウンロードしインストールします。</li> <li><a href="https://raw.githubusercontent.com/kojimaru14/box-jwt-postman/main/Postman%20Collections/Box-API-with-JWT.json">こちら</a>のPostman Collectionをインポートします。 <ul> <li>Postmanで「Import」をクリック ->「Link」のタブでURLを入力し「Continue」をクリック ->「Box API with JWT」を「Import」<br> <img src="https://drive.google.com/uc?id=1IEzCdd7XolxWnkahLX8ErOhTqIuh1E7z" alt="PostmanでBox APIを使ってみる (JWT認証)" loading="lazy"/></br></li> <li>もしくは、<a href="https://app.getpostman.com/run-collection/2871276-2075655c-1347-425d-bd5a-cb65b46c9992?action=collection%2Ffork&collection-url=entityId%3D2871276-2075655c-1347-425d-bd5a-cb65b46c9992%26entityType%3Dcollection%26workspaceId%3D53ed4f19-5241-41f3-a314-6b8891bbe925#?env%5BJWT%20-%20Template%5D=W3sia2V5IjoiY29uZmlnX2pzb24iLCJ2YWx1ZSI6IntcbiAgXCJib3hBcHBTZXR0aW5nc1wiOiB7XG4gICAgXCJjbGllbnRJRFwiOiBcIlwiLFxuICAgIFwiY2xpZW50U2VjcmV0XCI6IFwiXCIsXG4gICAgXCJhcHBBdXRoXCI6IHtcbiAgICAgIFwicHVibGljS2V5SURcIjogXCJcIixcbiAgICAgIFwicHJpdmF0ZUtleVwiOiBcIlwiLFxuICAgICAgXCJwYXNzcGhyYXNlXCI6IFwiXCJcbiAgICB9XG4gIH0sXG4gIFwiZW50ZXJwcmlzZUlEXCI6IFwiXCJcbn0iLCJlbmFibGVkIjp0cnVlLCJ0eXBlIjoiZGVmYXVsdCJ9XQ==">こちら</a>のボタンからコレクションをForkまたImport</li> </ul> </li> <li>Collectionがインポートされたら、そのCollectionのタイトル部分をクリックし、<a href="https://learning.postman.com/docs/sending-requests/variables/#defining-collection-variables">Collection環境変数</a>(当Collection内のみで有効の変数です)を設定します。 <ul> <li>"config_json" の[CURRENT VALUE]欄に先のBoxアプリ作成の手順でダウンロードされた config.json の内容をそのままコピペします。<br> <strong>注意:</strong> [INITIAL VALUE]欄には絶対貼り付けないでください。こちらにセットされた値はサーバーとの同期の対象になります。</br></li> <li>「INIT: Load crypto library for RS512」をクリックし「Send」を実行します。これにより "jsrsasign_js" の環境変数の値が更新されます。<br> <img src="https://drive.google.com/uc?id=1SyFpBFOD_RlLmKVZmbF_mtWPKnkBgROn" alt="PostmanでBox APIを使ってみる (JWT認証)" loading="lazy"/></br></li> </ul> </li> </ol> <p>これで準備完了です。</p> <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="box-api%E3%82%92%E5%91%BC%E3%82%93%E3%81%A7%E3%81%BF%E3%82%8B">Box APIを呼んでみる</h1> <p>それでは、Box APIを呼んでみましょう。「Get current user」を実行し、以下のように<a href="https://ja.developer.box.com/guides/getting-started/user-types/service-account/">サービスアカウント</a>の情報(<code>AutomationUser_AppServiceID_RandomString@boxdevedition.com</code>)が返ってきていれば成功です!<br> <img src="https://drive.google.com/uc?id=1HQfzXfSGhYhHkMGG0fXJV5CO3Yfi0Z3a" alt="PostmanでBox APIを使ってみる (JWT認証)" loading="lazy"/></br></p> <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="how-it-works">How it works</h1> <p>ここでは仕組みについて解説します。ざっくり言いますと、Postmanの<a href="https://learning.postman.com/docs/writing-scripts/pre-request-scripts/">Pre-request Script</a>という機能を使用して、リクエストを実行する手前で以下のロジックにて認証処理を行うことでAPIコールが行えるようにしてあります。</p> <p>基本的には公式の「<a href="https://ja.developer.box.com/guides/authentication/jwt/without-sdk/">SDKを使用しないJWT</a>」に記載のNode.jsのコードを踏襲してます。</p> <h3 id="1-configjson%E3%81%AE%E6%83%85%E5%A0%B1%E3%82%92%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%8B%E3%82%89%E5%8F%96%E5%BE%97">1. config.jsonの情報を環境変数から取得</h3> <pre><code class="language-javascript">const envConfig = pm.collectionVariables.get('config_json') const config = JSON.parse(envConfig); </code></pre> <h3 id="2-%E5%A4%96%E9%83%A8%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88">2. 外部ライブラリのインポート</h3> <p>JWTアサーションの生成にあたり、JWTクレームに署名をするための暗号化ライブラリを使用したいのですが、残念ながらPre-request ScriptのプラットフォームとなるPostman Sandbox上では標準提供されていないため、<code>require</code>でインポートすることができません。<br> 回避策(詳細は<a href="https://blog.postman.com/adding-external-libraries-in-postman/#load-a-library-from-a-variable">こちら</a>)として、環境変数として外部のライブラリのコードを丸ごと定義し、その環境変数をロードするという方法を使用します。それが以下の処理です。</br></p> <pre><code class="language-javascript">// Load the jsrsasign library into Postman Sandbox const navigator = {}; //fake a navigator object for the lib const window = {}; //fake a window object for the lib eval(pm.collectionVariables.get("jsrsasign_js")); //import javascript jsrsasign </code></pre> <p>ちなみに、前述の「INIT: Load crypto library for RS512」を実行する手順は、<a href="https://github.com/kjur/jsrsasign">jsrsasign</a>のレポジトリにあるコードをCollection環境変数"jsrsasign_js"へと書き込む処理です。</p> <h3 id="3-jwt%E3%82%A2%E3%82%B5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E7%94%9F%E6%88%90">3. JWTアサーションの生成</h3> <p><a href="https://github.com/kjur/jsrsasign">jsrsasign</a>にて秘密鍵でJWTクレームを署名し、JWTアサーションを作成します。</p> <pre><code class="language-javascript">// Generate random string for "jti" claim let newJti = ""; const charset = "abcdefghijklmnopqrstuvwxyz0123456789"; // At Box, it must be at least 16 characters and at most 128 characters // Ref: https://developer.box.com/guides/authentication/jwt/without-sdk/#3-create-jwt-assertion for( let i=0; i < 16; i++ ) { newJti += charset.charAt(Math.floor(Math.random() * charset.length)); } // Create Header and Payload objects const authenticationUrl = "https://api.box.com/oauth2/token"; let header = { "kid": config.boxAppSettings.appAuth.publicKeyID, "alg": 'RS512' }; let payload = { iss: config.boxAppSettings.clientID, sub: config.enterpriseID, box_sub_type: "enterprise", aud: authenticationUrl, jti: newJti, exp: Math.floor(Date.now() / 1000) + 45 }; const key = { key: config.boxAppSettings.appAuth.privateKey, passphrase: config.boxAppSettings.appAuth.passphrase }; const prvKey = KEYUTIL.getKey(key.key, key.passphrase); // Prep the objects for a JWT const sHeader = JSON.stringify(header); const sPayload = JSON.stringify(payload); const sJWT = KJUR.jws.JWS.sign(header.alg, sHeader, sPayload, prvKey); </code></pre> <h3 id="4-%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%82%92%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88">4. アクセストークンをリクエスト</h3> <p>JWTアサーションを送信しアクセストークンと交換します。</p> <pre><code class="language-javascript">pm.sendRequest({ url: 'https://api.box.com/oauth2/token', method: 'POST', headers: { 'Content-Type': 'Content-Type: application/x-www-form-urlencoded' }, body: { mode: 'urlencoded', urlencoded: [ { key: 'client_id', value: config.boxAppSettings.clientID, disabled: false }, { key: 'client_secret', value: config.boxAppSettings.clientSecret, disabled: false }, { key: 'assertion', value: sJWT, disabled: false }, { key: 'grant_type', value: 'urn:ietf:params:oauth:grant-type:jwt-bearer', disabled: false } ] } }, function (error, response) { if (error || response.json().error) { // if an error occured, log the error and raise a message to the user. console.log(error) console.log(response.json()) throw new Error('Could not get the access token. Check the console for more details.') } else { // otherwise, fetch the new access token and store it const data = response.json() // determine when this token is set to expire at const newExpiresAt = Date.now() + data.expires_in * 1000 // store the new variables in the environment pm.collectionVariables.set('jwt_access_token', data.access_token) pm.collectionVariables.set('jwt_expires_at', newExpiresAt) } }) </code></pre> <p>レスポンスで返ってきたアクセストークンはCollection環境変数"jwt_access_token"へと保存され、実際のリクエストが送信される際に使用されます(またトークンの有効期間内は次回以降のリクエスト実行時にも使用されます)。<br> <img src="https://drive.google.com/uc?id=1G_DVljCLuv5ES1OEZu0RMA9oFFSCB_dC" alt="PostmanでBox APIを使ってみる (JWT認証)" loading="lazy"/></br></p> <p>なお、トークンを失効させたい場合は、「Revoke access token」を実行することで可能です。このリクエストを実行すると、<a href="https://ja.developer.box.com/guides/authentication/tokens/revoke/">こちら</a>のAPIが送信されトークンが失効された後、リクエスト後の処理(<a href="https://blog.postman.com/writing-tests-in-postman/#what-is-a-test-in-postman">Tests</a>スクリプト)で以下が実行され、Collection環境変数からも削除されます。</p> <pre><code class="language-javascript">pm.collectionVariables.unset("jwt_expires_at"); pm.collectionVariables.unset("jwt_access_token"); </code></pre> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[CLI環境でCharles Proxyを利用して暗号化通信の中身を見る]]></title><description><![CDATA[ここでは、GUIを一切使用せずにCharles Proxyを使用して暗号化通信(HTTPS)のログをキャプチャする方法を紹介します。WindowsやMacなどGUIが使用できる環境ではCharles ProxyのGUIを使用して行えばいいのですが、LinuxサーバーなどGUIが使用できずCLIオンリーの環境で、通信のデバッグを行いたいという需要があったためリサーチしてこの方法にたどり着きました。 ※ちなみに別の方法として、環境変数SSLKEYLOGFILEを定義し、pre-master-secretをファイルへと出力しながらtcpdumpを採取するという手段もあると思います。 利用環境 * OS: Ubuntu 20.04.4 LTS (GNU/Linux 4.4.0-19041-Microsoft x86_64) 本稿では、Debian系のLinuxディストリビューションを使用してます(ちなみに上記バージョン情報の"Microsoft"からわかる通り、WSLのUbuntuです)が、Red hat系のディストリビューションでも(一部コマンドは異なるものの)同様の手順が]]></description><link>https://jikoblog.netlify.app/decrypt-tls-session-with-charles-proxy-on-cli/</link><guid isPermaLink="false">Ghost__Post__63a52ccc2bd3e300018606c7</guid><category><![CDATA[Proxy]]></category><category><![CDATA[Fiddler]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Mon, 09 Jan 2023 01:09:09 GMT</pubDate><media:content url="https://drive.google.com/uc?id=1MJJIUvlda3Drmn1AL8t48BJxAxbxjZpI" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://drive.google.com/uc?id=1MJJIUvlda3Drmn1AL8t48BJxAxbxjZpI" alt="CLI環境でCharles Proxyを利用して暗号化通信の中身を見る"/><p>ここでは、GUIを一切使用せずにCharles Proxyを使用して暗号化通信(HTTPS)のログをキャプチャする方法を紹介します。WindowsやMacなどGUIが使用できる環境ではCharles ProxyのGUIを使用して行えばいいのですが、LinuxサーバーなどGUIが使用できずCLIオンリーの環境で、通信のデバッグを行いたいという需要があったためリサーチしてこの方法にたどり着きました。<br> ※ちなみに別の方法として、環境変数<code>SSLKEYLOGFILE</code>を定義し、<a href="https://wiki.wireshark.org/TLS#using-the-pre-master-secret">pre-master-secret</a>をファイルへと出力しながら<code>tcpdump</code>を採取するという手段もあると思います。</br></p> <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="利用環境">利用環境</h1> <ul> <li>OS: <code>Ubuntu 20.04.4 LTS (GNU/Linux 4.4.0-19041-Microsoft x86_64)</code></li> </ul> <p>本稿では、Debian系のLinuxディストリビューションを使用してます(ちなみに上記バージョン情報の"Microsoft"からわかる通り、WSLのUbuntuです)が、Red hat系のディストリビューションでも(一部コマンドは異なるものの)同様の手順が実施可能な想定です。</p> <h1 id="installing-charles-proxy">Charles Proxyのインストール</h1> <p><a href="https://www.charlesproxy.com/documentation/installation/apt-repository/">Charles Proxyの公式サイト</a>に記載の手順に従ってCharles Proxyのインストールを行います(その記事に、各コマンドの解説も記載されてます)。</p> <pre><code class="language-bash">$ sudo apt-key adv --keyserver pgp.mit.edu --recv-keys 1AD28806 $ sudo sh -c 'echo deb https://www.charlesproxy.com/packages/apt/ charles-proxy main > /etc/apt/sources.list.d/charles.list' $ sudo apt-get update $ sudo apt-get install charles-proxy </code></pre> <p>インストール後、以下のコマンドを実行しバージョン情報が取得できればOKです。執筆時点ではバージョン4.6.3になりました。</p> <pre><code class="language-bash">$ charles -version Charles Proxy 4.6.3 </code></pre> <h1 id="installing-charles-root-ca">Charles Proxyのルート証明書のインストール</h1> <p>HTTPS通信の中身を確認するにあたり、Charles Proxyのルート証明書をエクスポートし、そのCAを信頼済みにする必要があります。</p> <p>エクスポートは<code>charles ssl export <file_name></code>で行えます。<br> Ref: <a href="https://www.charlesproxy.com/documentation/tools/command-line-tools/">https://www.charlesproxy.com/documentation/tools/command-line-tools/</a></br></p> <p>この例ではcharles.crtという名前で証明書をエクスポートします。</p> <pre><code class="language-bash">$ charles ssl export charles.crt </code></pre> <p>その後、その証明書を信頼済みCAとして登録します。まず証明書ファイル"charles.crt"をCAストアにコピーします。なんとなく<code>/usr/local/share/ca-certificates/</code>の直下に置くのは憚られたので"mycert"などサブディレクトリを作成して作業しました。</p> <pre><code class="language-bash">$ sudo mkdir /usr/local/share/ca-certificates/mycert </code></pre> <p>そこに証明書ファイルをコピーします。</p> <pre><code class="language-bash">$ sudo cp charles.crt /usr/local/share/ca-certificates/mycert/charles.crt </code></pre> <p>その後、CAストアをアップデートします。</p> <pre><code class="language-bash">$ sudo update-ca-certificates Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d... done. </code></pre> <p>すると、上記のように証明書が追加されたと標準出力に表示されます。</p> <h1 id="configuring-charles-proxy">Charles Proxyの設定</h1> <p>Charles Proxyの設定を行います。が、ここで悲報です。Charles Proxyでは<a href="https://www.charlesproxy.com/documentation/tools/command-line-tools/">Command-line Toolsの資料</a>を見る限り、設定を行うためのコマンドが用意されてないようです。</p> <p>ただ、どうやら他のプラットフォームの設定ファイルと互換があるようで、Windows版やMac版のCharles Proxyで使用した設定ファイルをそのままLinux版で使用することができました。なので、他のOS上でCharles ProxyのGUIから必要な設定を行い、その設定ファイルをLinux環境上にコピーして使用します。</p> <p>各プラットフォームにおける設定ファイルの保存場所は以下の通りです:</p> <ul> <li>Windows: <code>%APPDATA%\Charles\charles.config</code></li> <li>Mac OS X: <code>~/Library/Preferences/com.xk72.charles.config</code></li> <li>Linux: <code>~/.charles.config</code></li> </ul> <p>Ref: <a href="https://www.charlesproxy.com/documentation/faqs/deploying-license-keys-during-installation/">https://www.charlesproxy.com/documentation/faqs/deploying-license-keys-during-installation/</a></p> <p>私が使用した設定ファイルを<a href="https://app.box.com/s/ejhfzn7cco4tidmp3ovw3uqgffbvlliy">ここ</a>に記載させていただきます。</p> <p>設定ファイルをLinux上のホームディレクトリ<code>~/.charles.config</code>に保存する、もしくはCharles Proxy起動時に引数として指定する(以下のコマンド)ことで、その設定ファイルを読み込むことが可能です。</p> <pre><code class="language-bash">$ charles -config <config_file_name> </code></pre> <h3 id="%E9%87%8D%E8%A6%81%E3%81%AA%E8%A8%AD%E5%AE%9A%E9%A0%85%E7%9B%AE">重要な設定項目</h3> <p>ここではデフォ値と異なるであろう設定項目についていくつかピックアップします。</p> <p>SSL proxyingの対象ホスト・ポート</p> <pre><code class="language-xml"> <sslLocations> <locationPatterns> <locationMatch> <location> <host>*</host> <port>*</port> </location> <enabled>true</enabled> </locationMatch> </locationPatterns> </sslLocations> </code></pre> <p>Web interfaceの有効化</p> <pre><code class="language-xml"> <remoteControlConfiguration> <enabled>true</enabled> <allowAnonymous>true</allowAnonymous> <users/> </remoteControlConfiguration> </code></pre> <h1 id="running-charles-proxy">Charles Proxyの基本操作</h1> <p>設定ができたらCharles Proxyを起動してみましょう。以下のコマンドでプロセスを起動します。</p> <pre><code class="language-bash">$ charles </code></pre> <p>ライセンスを購入してない場合は、以下のように起動後10秒ほど待機時間が発生するので、Readyになるまで待ちます。</p> <pre><code class="language-bash">$ charles INFO com.xk72.charles.CharlesContext Loading Configuration INFO com.xk72.charles.CharlesContext Version 4.6.3 INFO com.xk72.charles.CharlesContext Loading Preferences Charles is shareware. If you continue using Charles you must pay the shareware fee. Charles will wait for 10 seconds before starting... INFO com.xk72.charles.CharlesContext Configuring Access Control List INFO com.xk72.charles.CharlesContext Starting Proxy Server INFO com.xk72.charles.CharlesContext Loading Tools INFO com.xk72.charles.CharlesContext Starting Tools INFO com.xk72.charles.CharlesContext Configuring Proxies INFO com.xk72.charles.CharlesContext Ready </code></pre> <p>Readyなったら起動完了です。</p> <p>そしたら、もう一つターミナル画面を開きます。Web interfaceを有効化していれば、以下のようにcurlでCharlesのWeb interface(<code>http://contorl.charles/</code>)にCharles Proxy(<code>http://127.0.0.1:8888</code>)をプロキシとしてアクセスすることで、Charles Proxyの様々な操作をすることが可能です。</p> <pre><code class="language-bash">$ curl -x http://127.0.0.1:8888 http://control.charles/ </code></pre> <p>レスポンスとして、Charles ProxyのメニューがHTMLで返ってきます。</p> <pre><code class="language-html"><html> <head> <title>Charles Web Interface</title> <link rel="stylesheet" href="css/plain.css" /> </head> <body> <h1>Charles Web Interface</h1> <ul> <li><a href="throttling/">Throttling</a></li> <li><a href="recording/">Recording</a></li> <li><a href="tools/">Tools</a></li> <li><a href="session/">Session</a></li> <li><a href="quit">Quit</a></li> </ul> </body> </html> </code></pre> <p>例えば、Recordingメニューを閲覧する場合は<code>recording/</code>のエンドポイント</p> <pre><code class="language-bash">curl -x http://127.0.0.1:8888 http://control.charles/recording/ </code></pre> <p>Sessionメニューを閲覧する場合は<code>session/</code>のエンドポイント</p> <pre><code class="language-bash">curl -x http://127.0.0.1:8888 http://control.charles/session/ </code></pre> <p>といった感じで操作が行えます。</p> <h1 id="recording-logs">Charles Proxyでログを採取</h1> <p>それではCharles Proxyで通信ログの採取を行ってみましょう。</p> <p>まず以下のコマンドででRecordingのメニューを開きます。</p> <pre><code class="language-html">$ curl -x http://127.0.0.1:8888 http://control.charles/recording/ <html> <head> <title>Charles Web Interface</title> <link rel="stylesheet" href="../css/plain.css" /> </head> <body> <h1>Charles Web Interface</h1> <h2>Recording</h2> <p>Status: Recording Stopped</p> <ul> <li><a href="start">Start</a></li> <li><a href="stop">Stop</a></li> <li><a href="../">Back</a></li> </ul> </body> </html> </code></pre> <p>上記より、Recordingの開始は<code>start</code>のエンドポイント、停止は<code>stop</code>のエンドポイントと分かります。</p> <p><code>start/</code>のエンドポイントにアクセスし、Recordingを開始します。</p> <pre><code class="language-html">$ curl -x http://127.0.0.1:8888 http://control.charles/recording/start <html> <head> <title>Charles Web Interface</title> <link rel="stylesheet" href="../css/plain.css" /> </head> <body> <h1>Charles Web Interface</h1> <h2>Recording</h2> <p>Status: Recording</p> <ul> <li><a href="start">Start</a></li> <li><a href="stop">Stop</a></li> <li><a href="../">Back</a></li> </ul> </body> </html> </code></pre> <p>上記のように"Status: Recording"というレスポンスが返っていれば、Recordingが開始されている状態です。</p> <p>その状態で、キャプチャしたい通信を行います。ここでは例として<code>curl</code>を使用した通信を行います。<br> まずcurlの通信がCharles Proxyを経由するように環境変数を定義してCharles Proxyをプロキシとして指定します。</br></p> <pre><code class="language-bash">export http_proxy='http://127.0.0.1:8888' export https_proxy='http://127.0.0.1:8888' </code></pre> <p>その後、通信を行います。</p> <pre><code class="language-bash">$ curl --location --request GET 'https://api.box.com/2.0/users/me' --header 'Authorization: Bearer 68l2JTE0wOQRM7tsC83ZDV8xl8GM11B0' </code></pre> <p>キャプチャしたい通信が完了したら、Charles ProxyでRecordingした内容をログファイルへと書き出します。</p> <p><code>session/</code>のエンドポイントにアクセスすることで、出力可能なフォーマットとそのコマンドを閲覧できます</p> <pre><code class="language-html">$ curl -x http://127.0.0.1:8888 http://control.charles/session/ <html> <head> <title>Charles Web Interface</title> <link rel="stylesheet" href="../css/plain.css" /> </head> <body> <h1>Charles Web Interface</h1> <h2>Session</h2> <ul> <li><a href="clear">Clear Session</a></li> <li><a href="export-xml">Export Session as XML</a></li> <li><a href="export-json">Export Session as JSON</a></li> <li><a href="export-trace">Export Session as Trace</a></li> <li><a href="export-csv">Export Session as CSV</a></li> <li><a href="export-har">Export Session as HAR</a></li> <li><a href="download">Download Session</a></li> <li><a href="../">Back</a></li> </ul> </body> </html> </code></pre> <p>例えば、JSONで保存する場合は<code>export-json</code>のエンドポイント</p> <pre><code class="language-bash">$ curl -x http://127.0.0.1:8888 http://control.charles/session/export-json --output <output_file_name> </code></pre> <p>Traceで保存する場合は<code>/export-trace</code>のエンドポイント</p> <pre><code class="language-bash">$ curl -x http://127.0.0.1:8888 http://control.charles/session/export-trace --output <output_file_name> </code></pre> <p>といった感じです。</p> <p>TraceファイルをCharles Proxyで開くことで、復号された通信の内容を確認することができます。</p> <p><img src="https://docs.google.com/uc?id=1TQZu2SU-SB5Uos58Lr2ATQQtatnhVohL" alt="CLI環境でCharles Proxyを利用して暗号化通信の中身を見る" loading="lazy"/></p> <h1 id="common-errors">Common Errors</h1> <h3 id="web-interface%E3%81%8C%E6%9C%89%E5%8A%B9%E5%8C%96%E3%81%95%E3%82%8C%E3%81%A6%E3%81%AA%E3%81%84">Web interfaceが有効化されてない</h3> <ul> <li>Error:</li> </ul> <pre><code class="language-html"><html> <head> <title>Charles Web Interface</title> </head> <body> <h1>Charles Web Interface</h1> <p>The Web Interface is disabled. You can enable it in the Web Interface Settings in the Proxy menu.</p> </body> </code></pre> <ul> <li>Cause: Web interfaceの有効化がされてない状態で、<code>http://control.charles</code>に接続が行われた。</li> <li>Solution: <a href="#%E9%87%8D%E8%A6%81%E3%81%AA%E8%A8%AD%E5%AE%9A%E9%A0%85%E7%9B%AE">この</a>手順を実施して、設定ファイルよりWeb Interfaceを有効化する。</li> </ul> <h3 id="charles-proxy%E3%81%A8%E3%81%AE%E6%8E%A5%E7%B6%9A%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84">Charles Proxyとの接続ができない</h3> <ul> <li>Error:</li> </ul> <pre><code class="language-bash">curl: (7) Failed to connect to 127.0.0.1 port 8888: Connection refused </code></pre> <ul> <li>Cause: Charles Proxyが起動してない、もしくは起動しているポート番号が8888とは異なっている。</li> <li>Solution: Charles Proxyが起動しているか確認、また接続先のポート番号と設定ファイルで指定されているポート番号(以下の箇所)が一致しているか確認する。</li> </ul> <pre><code class="language-xml"> <proxyConfiguration> <-- 略 --> <port>8888</port> <-- 略 --> </proxyConfiguration> </code></pre> <h3 id="ssl%E3%82%A8%E3%83%A9%E3%83%BC">SSLエラー</h3> <ul> <li>Error:</li> </ul> <pre><code class="language-bash">curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to 127.0.0.1:8888 </code></pre> <ul> <li>Cause: Charles ProxyのSSL証明書が信頼されていない。</li> <li>Solution: <a href="#installing-charles-root-ca">この</a>手順の証明書がインストールされていることを確認する。また、証明書インストール後、再起動が必要かも(自身がこのエラーにヒットした時は、OSの再起動で解消された記憶)。</li> </ul> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Ghost で任意の image url を Featured Image に指定する]]></title><description><![CDATA[Ghost で記事を作成する際、アイキャッチ画像(Featured Image)に外部ソースの画像を指定する方法について紹介します。 前置き ブログで記事を作成する際、画像や動画などのメディアは別のサーバー(AWS S3やGoogle Cloud Storageなど)で管理したい、ということはないでしょうか。 Ghostでは記事内の画像は外部URLを指定できるものの、残念ながらアイキャッチ画像(Featured Image)に関してはGhostサーバーにアップロードしたファイルしか指定できないようです。以下はForumの関連記事です。 Allow external URLs for feature imagesWould it be possible to have an option to enter the url for an already existing image as an alternative to uploading it? I see that the Unsplash option does just this, so I guess the ]]></description><link>https://jikoblog.netlify.app/ghost-choose-external-url-for-featured-images/</link><guid isPermaLink="false">Ghost__Post__62ca526f68d2c60001afd03e</guid><category><![CDATA[Ghost]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Sun, 10 Jul 2022 04:52:06 GMT</pubDate><media:content url="http://localhost:2368/content/images/2023/02/ghost-logo.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="http://localhost:2368/content/images/2023/02/ghost-logo.jpg" alt="Ghost で任意の image url を Featured Image に指定する"/><p>Ghost で記事を作成する際、アイキャッチ画像(Featured Image)に外部ソースの画像を指定する方法について紹介します。</p><!--kg-card-begin: markdown--><h1 id="前置き">前置き</h1> <p>ブログで記事を作成する際、画像や動画などのメディアは別のサーバー(AWS S3やGoogle Cloud Storageなど)で管理したい、ということはないでしょうか。</p> <p>Ghostでは記事内の画像は外部URLを指定できるものの、残念ながらアイキャッチ画像(Featured Image)に関してはGhostサーバーにアップロードしたファイルしか指定できないようです。以下はForumの関連記事です。</p> <!--kg-card-end: markdown--><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://forum.ghost.org/t/allow-external-urls-for-feature-images/5364"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Allow external URLs for feature images</div><div class="kg-bookmark-description">Would it be possible to have an option to enter the url for an already existing image as an alternative to uploading it? I see that the Unsplash option does just this, so I guess the heavy-lifting setup is already in place.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://aws1.discourse-cdn.com/business4/uploads/ghost2/optimized/2X/f/f381b3b952df5ad42fe691a8b14aa7f0c96c461a_2_180x180.png" alt="Ghost で任意の image url を Featured Image に指定する"><span class="kg-bookmark-author">Ghost Forum</span><span class="kg-bookmark-publisher">luciandavidescu</span></img></div></div><div class="kg-bookmark-thumbnail"><img src="https://aws1.discourse-cdn.com/business4/uploads/ghost2/original/2X/8/8d4e1be1543b3ed506f105953a0d062b84797e42.png" alt="Ghost で任意の image url を Featured Image に指定する"/></div></a></figure><!--kg-card-begin: markdown--><h1 id="やり方">やり方</h1> <p>上記記事の通り、Ghostのユーザーインターフェースからは外部URLは指定できないようなのですが、Ghostのデータベースを直接書き換えるという力業を使えば、無理くり外部URLを参照できるようになります。</p> <p><a href="https://ghost.org/docs/config/#database">Ghostのデータベース</a>に<code>posts</code>というテーブルがあり、そこに記事のレコードが登録されております。そのテーブルには<code>feature_image</code>という列があるので、対象のレコードのこのフィールドを任意の値で書き換えることで、実現ができます。</p> <p><img src="https://drive.google.com/uc?id=1jdprUFqrYEj1tXFBiNr9jpIWrj4xtKll" alt="Ghost で任意の image url を Featured Image に指定する" loading="lazy"/></p> <p><a href="https://jikoblog.netlify.app/ghost-gatsby-netlify/">こちら</a>の記事のようにローカル環境で動かしている場合は、ローカルの作業ディレクトリ配下に<code>ghost.db</code>というDBファイルがあるので、これを<a href="https://sqlitebrowser.org/">DB Browser</a>などで開き編集することで、簡単に書き換えることができます。</p> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Ghost + Gatsby + Netlify でブログを開設]]></title><description><![CDATA[Ghost + Gatsby + Netlify でブログを開設しましたので、手順についてメモします。以前は、WordPressを使ってブログを運用していたのですがメンテナンスに限界を感じ、別のCMSを探したところ、この構成にたどり着きました。この構成を使用することで、シンプルかつ高速なブログを作成することができました。 Tech stack ざっくりですが、使用した技術スタックについてひとことずつ * Ghost: コンテンツマネジメントシステム(CMS)。Ghostでブログを書きます。 * Gatsby: 静的サイトジェネレータ(Static Site Generator)。Ghostで作成したブログ記事を静的コンテンツへと変換します。 * Netlify: ホスティングサービス。Gatsbyで生成した静的コンテンツをここにホスティングし、Webで閲覧できるようにします。 利用環境 以下を使用しました * Docker version: 20.10.14, build a224086 * Node version: v16.15.0 * Ga]]></description><link>https://jikoblog.netlify.app/ghost-gatsby-netlify/</link><guid isPermaLink="false">Ghost__Post__62c60ff40b910a00012ac483</guid><category><![CDATA[Ghost]]></category><category><![CDATA[Docker]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Sun, 10 Jul 2022 02:23:11 GMT</pubDate><media:content url="https://ghost.org/images/docs/jamstack/admin-api-gatsby-diagram_hu088f0fec0d83414e79d90f8ae3457e19_21185_1000x0_resize_q100_h2_box_3.webp" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://ghost.org/images/docs/jamstack/admin-api-gatsby-diagram_hu088f0fec0d83414e79d90f8ae3457e19_21185_1000x0_resize_q100_h2_box_3.webp" alt="Ghost + Gatsby + Netlify でブログを開設"/><p>Ghost + Gatsby + Netlify でブログを開設しましたので、手順についてメモします。以前は、WordPressを使ってブログを運用していたのですがメンテナンスに限界を感じ、別のCMSを探したところ、この構成にたどり着きました。この構成を使用することで、シンプルかつ高速なブログを作成することができました。</p> <h1 id="Techstack">Tech stack</h1> <p>ざっくりですが、使用した技術スタックについてひとことずつ</p> <ul> <li>Ghost: コンテンツマネジメントシステム(CMS)。Ghostでブログを書きます。</li> <li>Gatsby: 静的サイトジェネレータ(Static Site Generator)。Ghostで作成したブログ記事を静的コンテンツへと変換します。</li> <li>Netlify: ホスティングサービス。Gatsbyで生成した静的コンテンツをここにホスティングし、Webで閲覧できるようにします。</li> </ul> <h1 id="利用環境">利用環境</h1> <p>以下を使用しました</p> <ul> <li>Docker version: <code>20.10.14, build a224086</code></li> <li>Node version: <code>v16.15.0</code></li> <li>Gatsby CLI: <code>4.15.0</code></li> <li>Netlify CLI: <code>netlify-cli/10.3.3 win32-x64 node-v16.15.0</code></li> </ul> <h1 id="Ghost">Ghost</h1> <p>CMSしてGhostを使用します。Ghostのホスティングサービスを利用すると有償になるのですが、オープンソースプロジェクトとしてソースコードを公開してくれているので、そちらを利用してローカル上でGhostサーバーを立てることができます。簡単にやる方法しては、以下の2通りになると思います。</p> <h4 id="docker%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B">Dockerを使用する</h4> <p>Ghost公式の<a href="https://hub.docker.com/_/ghost">Docker Image</a>があるので、それを利用します。作業ディレクトリに、<code>docker-compose.yml</code>を作成し、以下を記述します。</p> <pre><code class="language-yml">version: '3' services: ghost: image: ghost restart: always volumes: - ./ghost:/var/lib/ghost/content ports: - 2368:2368 </code></pre> <p>その後、以下のコマンドを実行すると、Ghostサーバーを <a href="http://localhost:2368/">http://localhost:2368/</a> で開始できます。</p> <pre><code>$ docker-compose up </code></pre> <p>なお、作業ディレクトリ直下に「ghost」というフォルダが作成され、そこに作成したコンテンツが保存されます。</p> <h4 id="ghost-cli%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B">Ghost CLIを使用する</h4> <p>Dockerを使用しなくても、<a href="https://ghost.org/docs/ghost-cli/">Ghost CLI</a>を利用することで、Ghostサーバーを立てることができます。CLIのインストールは以下のコマンドで行います。</p> <pre><code>$ npm install ghost-cli@latest -g </code></pre> <p>その後、作業ディレクトリで以下のコマンドを実行し、サーバーの起動に必要なモジュールのインストールを行います。</p> <pre><code>$ ghost install local </code></pre> <p>作業ディレクトリ配下のパス「<code>ghost/content</code>」に作成したコンテンツが保存されます。</p> <p>上記実施後、ブラウザで <a href="http://localhost:2368/">http://localhost:2368/</a> にアクセスすると、ローカルで起動しているGhostサーバーに接続できます。<br> <a href="http://localhost:2368/ghost">http://localhost:2368/ghost</a> にアクセスすると管理者ページに入ることができます。初回はユーザ未作成状態なので、「Create account」をクリックして管理者ユーザーを作成します。</br></p> <p><img src="https://drive.google.com/uc?id=1RDyu14zESgIdVIh-Dh62ufh-iX6WZypa" alt="Ghost + Gatsby + Netlify でブログを開設" loading="lazy"/></p> <p>その後、ダッシュボードから、[Settings] (ギアアイコン) > [Integrations] > [Add custom integration] と遷移し、任意の名前で新たなカスタム連携を作成します(このカスタム連携のAPI Keyは後の手順で使用します)。</p> <p><img src="https://drive.google.com/uc?id=18eL-ZSBVje0dNHxBJNfvdCUIzYcoG4fc" alt="Ghost + Gatsby + Netlify でブログを開設" loading="lazy"/></p> <p>ここまででGhostの準備は完了です。</p> <h1 id="Gatsby">Gatsby</h1> <p>次にGatsbyを使用して、Ghostサーバーのブログ記事を静的コンテンツ(Static HTML)へと変換する作業を行います。Ghostが公式の<a href="https://github.com/TryGhost/gatsby-starter-ghost">スターターテンプレート</a>を出しているのでそちらを利用します。もしくは、サードパーティーがテーマのプラグインを公開してくれているので、そちらも利用可能です。<a href="https://www.gatsbyjs.com/plugins/?=ghost">Gatsbyサイト</a>内で"ghost"でプラグインを検索して探すことができます(例: <a href="https://github.com/styxlab/gatsby-theme-try-ghost">https://github.com/styxlab/gatsby-theme-try-ghost</a> )。</p> <p>お好きなテンプレートをローカルへとクローンしてDependenciesのインストールを行います。</p> <pre><code>$ git clone https://github.com/TryGhost/gatsby-starter-ghost.git $ cd gatsby-starter-ghost $ yarn </code></pre> <p>Gatsby-CLIを利用する場合は以下のコマンドになります</p> <pre><code>$ gatsby new gatsby-starter-ghost https://github.com/TryGhost/gatsby-starter-ghost.git </code></pre> <p>その後、レポジトリ直下(「gatsby-starter-ghost」直下)の<code>.ghost.json</code>ファイルに先の手順で作成したGhostのカスタム連携のAPIキーを入力します。</p> <pre><code class="language-json">{ "development": { "apiUrl": "http://localhost:2368", "contentApiKey": "f64alfad618e7f896358ab0273" }, "production": { "apiUrl": "http://localhost:2368", "contentApiKey": "f64alfad618e7f896358ab0273" } } </code></pre> <p>ここまでできたら、<code>gatsby build</code>(もしくは<code>yarn build</code>)を実行すると <a href="http://localhost:2368/">http://localhost:2368/</a> のGhostサイトの静的コンテンツが生成できます。生成された静的コンテンツは、レポジトリ直下(「gatsby-starter-ghost」直下)の<code>public</code>フォルダに格納されます。</p> <p>ちなみに、<code>gatsby serve</code>(もしくは<code>yarn serve</code>)を実行すると、<a href="http://localhost:9000/">http://localhost:9000/</a> でGatsbyによってビルドされた静的コンテンツがどのように表示されるか確認することができます。</p> <h1 id="Netlify">Netlify</h1> <p>作成された静的コンテンツをNetlifyへとデプロイします。<a href="https://www.netlify.com/">Netlifyアカウント</a>を未作成の場合は、アカウントを作成し(無償でできます)、アプリを作成しておきます。</p> <p>レポジトリ直下に遷移した状態で、以下のコマンドを実行しNetlifyにログインします。</p> <pre><code>$ netlify login </code></pre> <p>その後、以下のコマンドでNetlifyにデプロイを行います。</p> <pre><code>$ netlify deploy -p </code></pre> <p>上記コマンド実施時に、デプロイ先のアプリ名などが聞かれるので、それらに回答すると静的コンテンツがNetlifyへとアップロードされ、Web上でページが閲覧できるようになります。</p> <h1 id="おさらい">おさらい</h1> <p>ブログ作成の流れをおさらいしていきます。</p> <p>ブログを更新する際は</p> <ol> <li>Ghostサーバーを起動し、ローカル上で編集を行います</li> <li>編集後、Gatsbyで静的コンテンツへと変換します</li> <li>静的コンテンツをNetlifyへとデプロイします</li> </ol> <p>フォルダ構成</p> <pre><code>- gatsby-starter-ghost/ |- src |- static |- .ghost.json <- これを編集する |- netlify.toml <- Netlifyのビルド設定 |- public <- ここにGatsbyでビルドした静的コンテンツが生成される |- package.json |- etc. - ghost/ <- Ghostサーバー(Docker)で作成したコンテンツがここに格納される(このフォルダはバックアップをすべき) |- apps |- data |- files |- images |- logs |- media |- public |- settings |- themes - docker-compose.yml </code></pre> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[PostmanでZaim APIを使ってみる]]></title><description><![CDATA[Postmanを使用してZaim APIを試してみました。Zaim APIは認証方式としてOAuth 1.0を利用しているようなのですが、その認証方式の前提知識なしでPostmanにてサクッと試したい方の参考になればと思います。 Zaim APIを利用するまでの流れ 以下の流れでZaim APIの利用が開始できます。 1. Zaimアプリを作成する 2. Zaimアプリを使用してアクセストークンを取得する 1. リクエストトークンを取得 2. ユーザーとしてログインしアプリを認可する 3. アクセストークンを取得 3. アクセストークンを使用してZaim APIを使用する ※事前にZaimのアカウントの作成とPostmanのインストールは完了している前提です。 1. Zaimアプリの作成 Zaim APIの使用にあたり、まずアプリの作成が必要になりますので、以下の手順で作成を行います。 1. Zaim Developer Center(https://dev.zaim.net/home)にログインします。 2. [新しい]]></description><link>https://jikoblog.netlify.app/zaim-api-with-postman/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3ef</guid><category><![CDATA[Zaim]]></category><category><![CDATA[Postman]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Sun, 15 May 2022 15:21:47 GMT</pubDate><media:content url="https://drive.google.com/uc?id=1MdEsZZC-0whnSq0w7Wdmsqy6vSq793LI" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://drive.google.com/uc?id=1MdEsZZC-0whnSq0w7Wdmsqy6vSq793LI" alt="PostmanでZaim APIを使ってみる"/><p>Postmanを使用してZaim APIを試してみました。Zaim APIは認証方式としてOAuth 1.0を利用しているようなのですが、その認証方式の前提知識なしでPostmanにてサクッと試したい方の参考になればと思います。</p> <h1 id="Zaim APIを利用するまでの流れ">Zaim APIを利用するまでの流れ</h1> <p>以下の流れでZaim APIの利用が開始できます。</p> <ol><li>Zaimアプリを作成する</li><li>Zaimアプリを使用してアクセストークンを取得する<ol><li>リクエストトークンを取得</li><li>ユーザーとしてログインしアプリを認可する</li><li>アクセストークンを取得</li></ol></li><li>アクセストークンを使用してZaim APIを使用する</li></ol> <p>※事前にZaimのアカウントの作成とPostmanのインストールは完了している前提です。</p> <h1 id="1. Zaimアプリの作成">1. Zaimアプリの作成</h1> <p>Zaim APIの使用にあたり、まずアプリの作成が必要になりますので、以下の手順で作成を行います。</p> <ol><li>Zaim Developer Center(<a rel="noopener" href="https://dev.zaim.net/home" target="_blank">https://dev.zaim.net/home</a>)にログインします。</li><li>[新しいアプリケーションを追加] を押下するとアプリの情報を入力する画面になるので、埋めていきます(基本的にいずれの項目も任意の値で大丈夫ですが、[アクセスレベル]については必要な権限のみを有効化しておくことがいいと思います)。</li></ol> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1XgXGiXGHM90Wzfk481mA96goXxV3banN" alt="PostmanでZaim APIを使ってみる" width="763" height="579"/></figure> <ol start="3" style="--previous-count: 2"><li>アプリの登録が完了したら、追加されたアプリの情報を確認します。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1zZGAZ_dd2XXs9S5FvCVSMUSzF2Vp_o9d" alt="PostmanでZaim APIを使ってみる"/></figure> <p>以下の情報はこの後の手順で使用するので控えておきます。</p> <ul><li>コンシューマ ID: 6f5ae0b1f7ce0944f9b28109607b949aa4ab7e97</li><li>コンシューマシークレット: 4d37fda7bcb84d8949910ca06ee3cb0e09659641</li></ul> <div class="wp-block-cocoon-blocks-icon-box common-icon-box block-box alert-box"> <p>コンシューマIDやコンシューマシークレット、またこの後に登場するトークンなどの情報は秘匿情報です。本記事ではマスキングせずに記載しております(執筆後、無効化して利用できなくしております)が、自身のものは外部に漏らさないようお気をつけください。</p> </div> <h1 id="2. アクセストークンを取得する">2. アクセストークンを取得する</h1> <p>手順1で作成したZaimアプリを使用してアクセストークンを取得します。</p> <h3 id="2-1. リクエストトークンを取得">2-1. リクエストトークンを取得</h3> <p>まず、リクエストトークン取得URL(https://api.zaim.net/v2/auth/request)を使用してリクエストトークンを取得します。Postmanで新規タブを開き、以下を入力してリクエストを送信します。</p> <ol><li>Request URL: https://api.zaim.net/v2/auth/request (リクエストトークン取得URL)</li><li>Method: GET</li><li>Authorizationタブで以下を設定<ol><li>Type: OAuth 1.0</li><li>Signature Method: HMAC-SHA1</li><li>Consumer Key: 6f5ae0b1f7ce0944f9b28109607b949aa4ab7e97 (コンシューマIDの文字列)</li><li>Consumer Secret: 4d37fda7bcb84d8949910ca06ee3cb0e09659641 (コンシューマシークレットの文字列)</li><li>Callback URL: http://localhost (空欄にはできないので、任意のURLを入力)</li></ol></li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1hEROKnKM0w-PIF-r-wrr7043ZCQDhbK5" alt="PostmanでZaim APIを使ってみる"/></figure> <p>リクエストを送信すると、レスポンスで以下が返ってきます。</p> <pre><code class="language-http">oauth_token=5ra2lInLI8MkJwqD9HGY2KKrVOMLyDe3qLYgesyMLrkmr2HeVAkujRl7OyyoRAaTbiyHkSEhPw&oauth_token_secret=xUfruOQ2h9zObc1sUKoPuPZOySP968YA9gGW7sVaJohqBxJ3BRq7y7eRxcInCzY8Fqsg&oauth_callback_confirmed=true </code></pre> <p>これらの値は後続の手順で使うので控えておきます。</p> <ul><li>oauth_token: 5ra2lInLI8MkJwqD9HGY2KKrVOMLyDe3qLYgesyMLrkmr2HeVAkujRl7OyyoRAaTbiyHkSEhPw</li><li>oauth_token_secret: xUfruOQ2h9zObc1sUKoPuPZOySP968YA9gGW7sVaJohqBxJ3BRq7y7eRxcInCzY8Fqsg</li></ul> <h3 id="2-2. ユーザーとしてログインしアプリを認可する">2-2. ユーザーとしてログインしアプリを認可する</h3> <p>次に、認証URL(https://auth.zaim.net/users/auth)を使用して、アプリの認可を行います。ブラウザを起動し、アドレスバーに以下のURLを入力します(<code>oauth_token</code>の値は、手順2-1で取得したものを使用)。</p> <pre><code class="language-http">https://auth.zaim.net/users/auth?oauth_token=J6CpTLv0Ye9Axq3AwHFtM7A59TuTx61HuywUaOwjLm5N2BLBDTTHdeDprgn066ZSiQLog </code></pre> <p>すると認証を求められるので、お使いのZaimユーザーとしてログインします。</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1mUUioR2rbHz2znJYe7syqmkXS83PTgJf" alt="PostmanでZaim APIを使ってみる" width="472" height="668"/></figure> <p>ログイン後、このようなページになります。</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1C7Na77dT_0i8ob-fQLPUUdZZLo7e-pWQ" alt="PostmanでZaim APIを使ってみる" width="752" height="295"/></figure> <p>本来ならCallback URLに設定されたURL(私の場合はhttp://localhost)にリダイレクトされるはずなのに、なぜかされない(Zaimの不具合?)ので一見失敗したように見えますが、開発者ツールを開くと、Verifierの情報が見えるので、その情報を控えておきます。</p> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1d6EaWgwmMVwkM2oy-Df5VLO0gj8tRLFJ" alt="PostmanでZaim APIを使ってみる"/></figure> <pre><code class="language-html"><div class="callback">http://localhost?oauth_token=5ra2lInLI8MkJwqD9HGY2KKrVOMLyDe3qLYgesyMLrkmr2HeVAkujRl7OyyoRAaTbiyHkSEhPw&oauth_verifier=MNIet9Pqi6qrwrklpsxB8zROwr1L9aQe7Qr58KEevDs1FeYfiuMLOkvXumSlHjuPtFuNiPkjA<div class="callback_end"></div></div> </code></pre> <h3 id="2-3. アクセストークンを取得">2-3. アクセストークンを取得</h3> <p>最後にアクセストークン取得URLを使用して、アクセストークンを取得します。Postmanでまた新たにタブを開き、以下の情報を入力してリクエストを送信します。</p> <ol><li>Request URL: https://api.zaim.net/v2/auth/access (アクセストークン取得URL)</li><li>Method: POST</li><li>Authorizationタブで以下を設定<ol><li>Type: OAuth 1.0</li><li>Signature Method: HMAC-SHA1</li><li>Consumer Key: 6f5ae0b1f7ce0944f9b28109607b949aa4ab7e97 (コンシューマIDの文字列)</li><li>Consumer Secret: 4d37fda7bcb84d8949910ca06ee3cb0e09659641 (コンシューマシークレットの文字列)</li><li>Access Token: 5ra2lInLI8MkJwqD9HGY2KKrVOMLyDe3qLYgesyMLrkmr2HeVAkujRl7OyyoRAaTbiyHkSEhPw</li><li>Token Secret: xUfruOQ2h9zObc1sUKoPuPZOySP968YA9gGW7sVaJohqBxJ3BRq7y7eRxcInCzY8Fqsg</li><li>Callback URL: 空欄</li><li>Verifier: MNIet9Pqi6qrwrklpsxB8zROwr1L9aQe7Qr58KEevDs1FeYfiuMLOkvXumSlHjuPtFuNiPkjA (手順2-2で取得したもの)</li></ol></li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=19uVf-NgB6bXZR9PCkxSrSSw25mGgyq7x" alt="PostmanでZaim APIを使ってみる"/></figure> <p>リクエストを送信すると、レスポンスで以下が返ってきます。</p> <pre><code class="language-http">oauth_token=b2nhZHrMHjgBVA5zm2uAKZzOX5yUcIRsjDBsvaYZ1ALX60Wp97Q5LDt7zL7xCvnYTMVjhew&oauth_token_secret=xUfruOQ2h9zObc1sUKoPuPZOySP968YA9gGW7sVaJohqBxJ3BRq7y7eRxcInCzY8Fqsg </code></pre> <p>この手順で返ってきたoauth_tokenとoauth_token_secretで、ZaimのAPIを使用することができます。</p> <ul><li>oauth_token: b2nhZHrMHjgBVA5zm2uAKZzOX5yUcIRsjDBsvaYZ1ALX60Wp97Q5LDt7zL7xCvnYTMVjhew</li><li>oauth_token_secret: xUfruOQ2h9zObc1sUKoPuPZOySP968YA9gGW7sVaJohqBxJ3BRq7y7eRxcInCzY8Fqsg </li></ul> <h1 id="3. Zaim APIを使用してみる">3. Zaim APIを使用してみる</h1> <p>Postmanでまた新たにタブを開き、以下の情報を入力します。</p> <ol><li>Request URL: https://api.zaim.net/v2/home/user/verify (<a rel="noopener" href="https://dev.zaim.net/home/api#user_verify" target="_blank">ユーザー情報取得エンドポイント</a>)</li><li>Method: GET</li><li>Authorizationタブで以下を設定<ol><li>Type: OAuth 1.0</li><li>Signature Method: HMAC-SHA1</li><li>Consumer Key: 6f5ae0b1f7ce0944f9b28109607b949aa4ab7e97 (コンシューマIDの文字列)</li><li>Consumer Secret: 4d37fda7bcb84d8949910ca06ee3cb0e09659641 (コンシューマシークレットの文字列)</li><li>Access Token: b2nhZHrMHjgBVA5zm2uAKZzOX5yUcIRsjDBsvaYZ1ALX60Wp97Q5LDt7zL7xCvnYTMVjhew (手順2-3で取得したもの)</li><li>Token Secret: xUfruOQ2h9zObc1sUKoPuPZOySP968YA9gGW7sVaJohqBxJ3BRq7y7eRxcInCzY8Fqsg</li><li>Callback URL: 空欄</li><li>Verifier: 空欄</li></ol></li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=14oxkxUFt3FG0ORMzsbsfqoeiLyyEk6Ho" alt="PostmanでZaim APIを使ってみる"/></figure> <p>レスポンスとしてユーザー情報が返ってきます。</p> <pre><code class="language-json">{ "me": { "login": "72904a1866b2", "input_count": 2, "day_count": 2, "repeat_count": 1, "id": 8626511, "currency_code": "JPY", "week": 0, "month": 1, "active": 1, "day": 1, "profile_modified": "2021-11-29 07:16:06", "name": "kojimaru", "created": "2021-11-29 07:15:40", "profile_image_url": "https://s3-ap-northeast-1.amazonaws.com/zaim.net/public/images/users/_default/90x90.png", "cover_image_url": "https://s3-ap-northeast-1.amazonaws.com/zaim.net/public/images/covers/_default/90x90.png" }, "requested": 1652588562 } </code></pre> <p>ほかのAPIエンドポイントも、同じ認証情報を使用して利用可能です。以下がデベロッパー向けのドキュメントへのリンクです(ログイン必須)。</p> <p>Ref: <a rel="noopener" href="https://dev.zaim.net/home/api" target="_blank">https://dev.zaim.net/home/api</a></p> <h1 id="トークンの無効化">トークンの無効化</h1> <p>Zaim APIにはトークンを無効化するエンドポイントは用意されてない(ドキュメントには見当たらず)ようなので、UIからやる必要があるようです。私が見つけた手順は以下の通りです。</p> <ol><li>Zaimに<a rel="noopener" href="https://zaim.net/" target="_blank">https://zaim.net/</a>よりログインする</li><li>ログイン後、右上の[設定]より[ソーシャルログイン]を選択する</li><li>[Zaim で認証]以下に認証済みアプリの一覧が出てくるので、その中で対象のアプリを見つけ[無効にする]を押下する</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1miMs6Y3LcCqBZswbZ1LdvwdcHGgB2fLq" alt="PostmanでZaim APIを使ってみる"/></figure> <ol start="4" style="--previous-count: 3"><li>その後は、上記手順で払い出したトークンが利用できなくなり、APIを利用すると認証エラー(<code>401 Unauthorized</code>)になる</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1utwF_6_Gfl4qkhDGfGaEaDpPk6M5gyIC" alt="PostmanでZaim APIを使ってみる"/></figure> <p/> <p/> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Wordpressのサーバー移行時に、旧サーバーで管理画面だけ入れるようにする方法]]></title><description><![CDATA[WordPressのお引越し(ドメイン変更を含む)をした後、旧サーバーの管理画面にどうしても入る必要ができてしまいました。が、旧ドメインから新ドメインへのリダイレクトが設定済みだったので、旧サーバーにアクセスしても新サーバーにリダイレクトされて旧サーバーの管理画面に入れない状態に。。。回避方法を見つけたのでメモしておきます。 やりたいこと * ページの訪問者が、旧サーバーのページにアクセスした際は、新サーバーにリダイレクトする。 * WordPressの管理者だけは、旧サーバーの管理画面にアクセスした際、新サーバーにリダイレクトせず管理画面を使用できるようにする。 対処方法 自身の検証より、Wordpressの管理画面に接続する際は、基本的に以下のパスが使用されることに気づきました。 https://old_domain.com/wp/xxx https://old_domain.com/app/xxx /wp/もしくは/app/で始まるパスが使用されるようなので、これらのパスにアクセスがあった場合はリダイレクトしないように設定を書き換えることで実現で]]></description><link>https://jikoblog.netlify.app/wordpress-configuring-redirection-during-migration/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3ee</guid><category><![CDATA[WordPress]]></category><category><![CDATA[Heroku]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Sun, 15 May 2022 08:04:36 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1cstzCmZOSgtdLl-2mT7jFzfnrr8VJOtu" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1cstzCmZOSgtdLl-2mT7jFzfnrr8VJOtu" alt="Wordpressのサーバー移行時に、旧サーバーで管理画面だけ入れるようにする方法"/><p>WordPressのお引越し(ドメイン変更を含む)をした後、旧サーバーの管理画面にどうしても入る必要ができてしまいました。が、旧ドメインから新ドメインへのリダイレクトが設定済みだったので、旧サーバーにアクセスしても新サーバーにリダイレクトされて旧サーバーの管理画面に入れない状態に。。。回避方法を見つけたのでメモしておきます。</p> <h1 id="やりたいこと">やりたいこと</h1> <ul><li>ページの訪問者が、旧サーバーのページにアクセスした際は、新サーバーにリダイレクトする。</li><li>WordPressの管理者だけは、旧サーバーの管理画面にアクセスした際、新サーバーにリダイレクトせず管理画面を使用できるようにする。</li></ul> <h1 id="対処方法">対処方法</h1> <p>自身の検証より、Wordpressの管理画面に接続する際は、基本的に以下のパスが使用されることに気づきました。</p> <pre><code class="language-url">https://old_domain.com/wp/xxx https://old_domain.com/app/xxx </code></pre> <p><code>/wp/</code>もしくは<code>/app/</code>で始まるパスが使用されるようなので、これらのパスにアクセスがあった場合はリダイレクトしないように設定を書き換えることで実現できました。</p> <h1 id="設定内容">設定内容</h1> <p>リダイレクトの設定は様々な方法でできると思いますが、私の場合は<code>nginx.conf</code>の設定でこれを行いました。</p> <p>私の場合、移行元のサーバーではHeroku上で<a rel="noopener" href="https://github.com/PhilippHeuer/wordpress-heroku/blob/743707d0bcd6de62bc95217c6f2a78d0d5fa745c/Procfile#L1" target="_blank">Nginx</a>をWebサーバーとして使用していたので、<code>nginx.conf</code>(<a rel="noopener" href="https://github.com/PhilippHeuer/wordpress-heroku/blob/743707d0bcd6de62bc95217c6f2a78d0d5fa745c/config/heroku/nginx.conf#L27" target="_blank">この</a>辺)に以下を追記しました(Apacheをご利用の方は、<code>.htaccess</code>の変更が必要になると思います)</p> <pre class="wp-block-code"><code>location ~* ^/(?!(wp|app)/) { rewrite ^ https://new_domain.com$request_uri? permanent; }</code></pre> <p>上記は、<code>/wp/</code>もしくは<code>/app/</code>で<strong>始まらない</strong>パスである場合のみ、新サーバーにリダイレクトを行うという設定になります(<a rel="noopener" href="https://regex101.com/r/JiO5ak/1" target="_blank">正規表現チェッカー</a>で確認できます)。</p> <p>参考記事: <a rel="noopener" href="https://stackoverflow.com/questions/16302897/nginx-location-not-equal-to-regex#answer-39549548" target="_blank">https://stackoverflow.com/questions/16302897/nginx-location-not-equal-to-regex#answer-39549548</a></p> <p>設定後は、以下のURLに直接行くと、新サーバーにリダイレクトされずに旧ドメインで管理画面に入れるようになりました。</p> <pre class="wp-block-code"><code>https://old_domain.com/wp/wp-admin/</code></pre> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Wordpressアップデート後、管理画面に入れない]]></title><description><![CDATA[WordPressのバージョンをアップデートした後、管理画面に入ろうとすると/wp/wp-admin/upgrade.php?_wp_http_referer=%2Fwp%2Fwp-admin%2Fへとリダイレクトされ続け、「更新の必要はありません WordPress のデータベースはすでに最新です !」と表示されて、入れなくなってしまいました。解決方法について記載します。 発生原因 この画面にリダイレクトされる原因は、Wordpressのバージョンアップ後、Wordpressのバージョン情報がウェブサーバー側とデータベース側とで一致しないことで起きるようです。 Ref: https://github.com/WordPress/WordPress/blob/master/wp-admin/admin.php#L51-L55 対処方法 ということで、Wordpressのバージョンをデータベース側のバージョンと比較してみました。 WordPressのバージョンはwp-includes/version.phpのwp_db_versionにセットされています。 ]]></description><link>https://jikoblog.netlify.app/wordpress-unable-to-login/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3ed</guid><category><![CDATA[WordPress]]></category><category><![CDATA[Heroku]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Sat, 14 May 2022 22:25:18 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1RI6xDoY7ZqCMa1KSFhvJ0sCTEZUs7TKV" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1RI6xDoY7ZqCMa1KSFhvJ0sCTEZUs7TKV" alt="Wordpressアップデート後、管理画面に入れない"/><p>WordPressのバージョンをアップデートした後、管理画面に入ろうとすると<code>/wp/wp-admin/upgrade.php?_wp_http_referer=%2Fwp%2Fwp-admin%2F</code>へとリダイレクトされ続け、「更新の必要はありません WordPress のデータベースはすでに最新です !」と表示されて、入れなくなってしまいました。解決方法について記載します。</p> <h1 id="発生原因">発生原因</h1> <p>この画面にリダイレクトされる原因は、Wordpressのバージョンアップ後、Wordpressのバージョン情報がウェブサーバー側とデータベース側とで一致しないことで起きるようです。</p> <p>Ref: <a rel="noopener" href="https://github.com/WordPress/WordPress/blob/master/wp-admin/admin.php#L51-L55" target="_blank">https://github.com/WordPress/WordPress/blob/master/wp-admin/admin.php#L51-L55</a></p> <h1 id="対処方法">対処方法</h1> <p>ということで、Wordpressのバージョンをデータベース側のバージョンと比較してみました。</p> <p>WordPressのバージョンは<code>wp-includes/version.php</code>の<code><a rel="noopener" href="https://github.com/WordPress/WordPress/blob/04f9d9bdf6028e95afdb5a135883ec1da74c6958/wp-includes/version.php#L26" target="_blank">wp_db_version</a></code>にセットされています。</p> <pre><code class="language-bash">$ heroku run bash -a jikoblog Running bash on ⬢ jikoblog... up, run.4394 (Free) ~ $ pwd /app ~ $ grep "wp_db_version =" web/wp/wp-includes/version.php $wp_db_version = 51917; </code></pre> <p>データベース側では、<code>wp_options</code>テーブルの<code>db_version</code>というカラムにセットされています。</p> <figure class="wp-block-image size-large is-style-default"><img src="https://docs.google.com/uc?id=1361zfNsAYJCzdeuofRkU79cp3jpyj8vy" alt="Wordpressアップデート後、管理画面に入れない"/></figure> <p>ここで両者のバージョンがなぜか一致してない場合は、Wordpressのバージョン(<code>$wp_db_version</code>)をデータベースに格納されているバージョン(<code>wp_options</code>の<code>db_version</code>)と合わせてあげることで、とりあえず例の画面は突破し管理画面に入れるようになると思います。</p> <p>ちなみに、私の場合は↑の通りバージョンが両方とも51917で一致してました。にも関わらず、本現象が起きており数時間ほど迷ってしまったのですが、結果的に犯人はRedisサーバーでした。アップデート作業時にRedisの情報が更新されてなかったようで、、、<code>heroku redis:cli</code>でHerokuのRedisに接続し、<code>flushall</code>コマンドでRedisのデータをクリーンアップしたら、その後はMySQLデータベースの最新の情報が取得され、現象が解消し管理者ページには入れるようになりました。</p> <pre><code class="language-bash">$ heroku redis:cli Connecting to redis-asymmetrical-69722 (HEROKU_REDIS_MAUVE_TLS_URL, HEROKU_REDIS_MAUVE_URL, REDIS_TLS_URL, REDIS_URL): ec2-44-196-208-213.compute-1.amazonaws.com:22940> flushall OK </code></pre> <p>ほかにもパフォーマンス向上のためのキャッシュ関連のプラグインを利用していると、私のようにデータベースは更新されているのに、キャッシュの情報が参照されていることで同様の現象になることが起こりうると思います。ご注意を!</p> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[WMware Workspace ONE + Android Enterprise + Box を設定してみた]]></title><description><![CDATA[WMware Workspace ONEをMDMとしてAndroid Enterpriseを利用し、Box for EMMを設定してみました。手順をメモっときます。 ※Intuneの時と同様、公式の資料がないところは割と手探りでやりました。間違い等ございましたら、ご指摘いただけますと幸いです。 VMware Workspace ONE 側の設定 (Android Enterprise編) こちらの公式の資料の手順に従って、Workspace ONE側でAndroid Enterpriseの設定を行います。ここでは本手順の内容をかいつまんで記載します。うちはGSuiteユーザーではないので、GSuiteユーザーでない方の手順を使用してます。 1. [はじめに] > [Workspace ONE] > [Android EMM 登録] の順に進み、[構成]を選択します。 ※私はすでに登録済みなので[構成]ではなく[編集]ボタンになっております。 2. 「Android EMM 登録」 ページにリダイレクトされるので、[Google に登録する] を選択しま]]></description><link>https://jikoblog.netlify.app/wmware-workspace-one-android-enterprise-box/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3ec</guid><category><![CDATA[Box]]></category><category><![CDATA[モバイル]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Thu, 29 Apr 2021 08:27:29 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1gse0MqKlLPTFu6aoPBJQ-1ihQngcm8VP" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1gse0MqKlLPTFu6aoPBJQ-1ihQngcm8VP" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた"/><p>WMware Workspace ONEをMDMとしてAndroid Enterpriseを利用し、<a href="https://support.box.com/hc/ja/articles/360043694974-Box-for-EMM%E3%81%AE%E6%A6%82%E8%A6%81%E3%81%A8FAQ">Box for EMM</a>を設定してみました。手順をメモっときます。<br> ※<a href="https://jikoblog.netlify.app/box-microsoft-intune-mam-without-enrollment/">Intune</a>の時と同様、公式の資料がないところは割と手探りでやりました。間違い等ございましたら、ご指摘いただけますと幸いです。</br></p> <h1 id="VMware Workspace ONE 側の設定 (Android Enterprise編)">VMware Workspace ONE 側の設定 (Android Enterprise編)</h1> <p><a rel="noopener" href="https://docs.vmware.com/jp/VMware-Workspace-ONE-UEM/services/Android_Platform/GUID-AndroidRegistrationRegisterAndroidwithWorkspaceONE.html#-google-play--android-emm--0" target="_blank">こちら</a>の公式の資料の手順に従って、Workspace ONE側でAndroid Enterpriseの設定を行います。ここでは<a rel="noopener" href="https://docs.vmware.com/jp/VMware-Workspace-ONE-UEM/services/Android_Platform/GUID-AndroidRegistrationRegisterAndroidwithWorkspaceONE.html#-google-play--android-emm--0" target="_blank">本手順</a>の内容をかいつまんで記載します。うちはGSuiteユーザーではないので、GSuiteユーザーでない方の手順を使用してます。</p> <ol><li><strong>[はじめに]</strong> > <strong>[Workspace ONE]</strong> > <strong>[Android EMM 登録]</strong> の順に進み、<strong>[構成]</strong>を選択します。<br>※私はすでに登録済みなので<strong>[構成]</strong>ではなく<strong>[編集]</strong>ボタンになっております。</br></li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=16qglidvoQ0ZIaqutUncbr45IwGVi401-" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-509"/><figcaption>© 2021 VMware, Inc</figcaption></figure> <ol start="2" style="--previous-count: 1"><li>「Android EMM 登録」 ページにリダイレクトされるので、<strong>[Google に登録する]</strong> を選択します。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1KC2JLL1ere2JIfuOY-at5NpZStjzYroP" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-511"/><figcaption>© 2021 VMware, Inc</figcaption></figure> <ol start="3" style="--previous-count: 2"><li>Googleアカウントでサインインし、開始 を選択します。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1fLM6d6kLhJX3rJJhgB9cU4W5kqdm5AK-" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-508"/><figcaption>© 2021 Google</figcaption></figure> <ol start="4" style="--previous-count: 3"><li><strong>組織名</strong> などの項目を入力し、<strong>[確認]</strong> > <strong>[登録を完了]</strong> の順に選択すると、Workspace ONE コンソールにリダイレクトされます。Google サービス アカウント認証情報が自動的に入力されているので、<strong>[保存]</strong> を選択します。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1jc6f-AjP4tUBC5kctqms6kJJ47h0kCHO" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-510"/><figcaption>© 2021 VMware, Inc</figcaption></figure> <h1 id="VMware Workspace ONE 側の設定 (Box編)">VMware Workspace ONE 側の設定 (Box編)</h1> <p><a rel="noopener" href="https://docs.vmware.com/jp/VMware-Workspace-ONE-UEM/services/Application_Management-for-Android/GUID-AWT-ADD-APPS.html" target="_blank">こちら</a>の公式の資料の手順を参考に、Box for Androidを管理対象アプリケーションとしてデバイスにプッシュするための設定を行います。</p> <ol start="0" style="--previous-count: -1"><li>いきなり資料の手順とそれますが、まず事前準備として<strong>[Public ID]</strong>の発行を<a rel="noopener" href="https://support.box.com/hc/ja/requests/new" target="_blank">Boxサポート</a>に依頼します。<strong>[Public ID]</strong>は後述の手順で使うのですが、発行のリードタイムが発生するので、事前に依頼しておきましょう。必要情報は<a rel="noopener" href="https://cloud.box.com/s/4zzh37b7yhb879480ribddm10xkpmvxp#p=4" target="_blank">こちら</a>を参照。</li><li>Workspace ONE UEM コンソールで、[アプリケーションとブック] > [アプリケーション] > [リスト ビュー] > [公開] の順に移動して、[アプリケーションを追加] を選択します。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=140KmSbZAYTyOKsu_tEkgQNzPgGI0Mx8w" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-517"/><figcaption>© 2021 VMware, Inc</figcaption></figure> <ol start="2" style="--previous-count: 1"><li>[プラットフォーム] でAndroidを選択し、[名前] テキスト ボックスに、アプリケーション ストアで Box for Android を検索するためのキーワードとして「Box」を入力します。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1hQXlk9p0iPXvN8R2wSMD2OHULPGQN8TB" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-514"/><figcaption>© 2021 VMware, Inc</figcaption></figure> <ol start="3" style="--previous-count: 2"><li>[次へ] を選択し、検索結果の中から「Box」を選択します。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=14Cp4W8hUujvJnYYU9Ef8p1p5woimN5VA" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-513"/><figcaption>© 2021 VMware, Inc</figcaption></figure> <ol start="4" style="--previous-count: 3"><li>デバイスでBoxアプリに必要な権限を確認し、[承認] を選択します。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1j-J5zRxHrPoal3IbD64ugIsW06am9hF1" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-512"/><figcaption>© 2021 VMware, Inc</figcaption></figure> <ol start="5" style="--previous-count: 4"><li>[詳細]、[利用規約]、[SDK] を必要に応じて設定し、[保存して割り当て] を選択してアプリを保存します。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1PEe-EBs70YTPy0krYDFMq3W85YnVMMTf" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-518"/><figcaption>© 2021 VMware, Inc</figcaption></figure> <ol start="6" style="--previous-count: 5"><li>保存後、[割り当て] タブに遷移するので、「割り当てを追加」 を選択し、<a rel="noopener" href="https://docs.vmware.com/jp/VMware-Workspace-ONE-UEM/services/Application_Management-for-Android/GUID-AWT-ASSIGN-APPS-FP02.html#GUID-AWT-ASSIGN-APPS-FP02" target="_blank">こちら</a>の公式資料を参考に必要な詳細を構成します(例: 必要なユーザーグループを割り当てる、など)。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1iA1VLJ6zqO-FgFwAFb7ceriitRKZfEGI" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-519"/><figcaption>© 2021 VMware, Inc</figcaption></figure> <ol start="7" style="--previous-count: 6"><li>[<strong>アプリケーション構成</strong>]の部分は、以下の設定が必要になります。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1Fj83aRifR4ZWCxA74G-paegeQNUR6IZj" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-520"/><figcaption>© 2021 VMware, Inc</figcaption></figure> <ul><li>User email: {EmailAddress}</li><li>Public Id: [手順#0でBoxサポートから提供された文字列を入力]</li><li>Management Id: {ManagementID}</li><li>EMM Name: Airwatch</li><li>Billing Id: [任意の文字列]</li><li>Intune Enterprise: 0</li><li>Microsoft User Principal Name: [任意の文字列]</li></ul> <p>上記設定後、保存を押したらWorkspace ONE UEMコンソールでの作業は完了です!</p> <h1 id="モバイル端末(Android)側の設定">モバイル端末(Android)側の設定</h1> <p>モバイル端末をWorkspace ONEの管理下とし、その後Box for Androidをインストールします。</p> <ol><li>Google Playストアより「Intelligent Hub」アプリをインストールします。</li></ol> Ref: https://play.google.com/store/apps/details?id=com.airwatch.androidagent&hl=ja&gl=US <ol start="2" style="--previous-count: 1"><li>「Intelligent Hub」アプリを開き、お使いのWorkspace ONE環境の情報を入力しユーザー認証を行います。</li></ol> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1giLo1P-UlBaZN_SlNU00s_EprhiWCcdp" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-521" width="270" height="480"/></figure> <ol start="3" style="--previous-count: 2"><li>ユーザー認証後、利用規約など同意を求められるので、諸々同意して進みます。</li></ol> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=14xOUFuD-xs9mnd2DvRhS7woWFcn61ZbV" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-522" width="270" height="480"/></figure> <ol start="4" style="--previous-count: 3"><li>一通り進めると、<a rel="noopener" href="https://support.google.com/work/android/answer/6191949?hl=ja" target="_blank">仕事用プロファイル</a>のセットアップが開始されます。</li></ol> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1ngysTGE9_3j7Fg13lEH25zbeK0lIyq2J" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-523" width="270" height="480"/></figure> <ol start="5" style="--previous-count: 4"><li>セットアップが完了すると、仕事用プロファイルのアプリ(カバンのマークが入ったもの)が追加されます。</li></ol> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=16GhhZ4YU0CUej6m2PokYaUJhLlg7lPDv" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-524" width="270" height="480"/></figure> <ol start="6" style="--previous-count: 5"><li>仕事用プロファイルの「Play Store」を開くと、「Box」アプリが表示されます。</li></ol> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=100udyvp0KYN3453AtwJSSpinJTYW9XOF" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-525" width="270" height="480"/></figure> <p>こちらをインストールすると仕事用プロファイルの(Workspace ONE管理下の)Boxアプリが端末にプロビジョンされます。</p> <h1 id="事後確認">事後確認</h1> <p>仕事用プロファイルのBoxアプリを開き、ログインが行えるか確認を行います。</p> <p>自社Boxインスタンス内のユーザーであれば、ログインが可能です。ちなみに、Boxのユーザーアクティビティレポートでは、「Box for Android EMM Phone」からのログインとして記録されるようです。</p> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1eLRUG74s_1f6n9zdbwpsJwLD8OSD86VJ" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-527"/></figure> <p>しかし、自社Boxインスタンス外のユーザーであれば、ログインが失敗します。</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1PbPMtNxMGW1PcP7LUJUHuTk-y_kqGJIf" alt="WMware Workspace ONE + Android Enterprise + Box を設定してみた" class="wp-image-526" width="270" height="480"/></figure> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[HiveQLでMIMEエンコードされたデータをデコードする]]></title><description><![CDATA[アプリケーションログの保存先として使用しているHiveにMIMEエンコードされた状態で保存されていたデータがあったので、HiveQLでデコードする方法を考えてみました。HiveQLの関数だけでやろうとするとあまりいい方法が思いつきませんでしたが、とりあえず実現する方法は編み出したのでメモっときます。 はじめに - HiveQLとは HiveQLとは一言でいうとHive上で使用できるSQLに似たクエリ言語になります。Hiveって何?って方は、こちらのページの説明がわかりやすいと思ったので、リンクさせていただきます。 要点をまとめると、Hive (Apache Hive) とはSQL(厳密にはHiveQLというSQLに近い言語)を使用してHDFS (Hadoop Distributed File System)のデータを集計・分析することを可能にするソフトウェアです。HDFSは複数のコンピューターのハードディスクを一つのストレージのように扱えるスケーラブルな分散型ファイルシステムであり、大規模なデータを格納できますが、データ集計を行う際MapReduceジョブ(各コンピュータ]]></description><link>https://jikoblog.netlify.app/hiveql-decoding-mime-encoded-data/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3eb</guid><category><![CDATA[SQL]]></category><category><![CDATA[Hive]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Sat, 17 Apr 2021 17:30:10 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1X7wost7HljajFVgXEGq5UEDbNZJXL85s" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1X7wost7HljajFVgXEGq5UEDbNZJXL85s" alt="HiveQLでMIMEエンコードされたデータをデコードする"/><p>アプリケーションログの保存先として使用しているHiveにMIMEエンコードされた状態で保存されていたデータがあったので、HiveQLでデコードする方法を考えてみました。HiveQLの関数だけでやろうとするとあまりいい方法が思いつきませんでしたが、とりあえず実現する方法は編み出したのでメモっときます。</p> <h1 id="はじめに - HiveQLとは">はじめに - HiveQLとは</h1> <p>HiveQLとは一言でいうとHive上で使用できるSQLに似たクエリ言語になります。Hiveって何?って方は、<a rel="noopener" href="https://www.idcf.jp/words/hive.html" target="_blank">こちら</a>のページの説明がわかりやすいと思ったので、リンクさせていただきます。</p> <p>要点をまとめると、Hive (Apache Hive) とはSQL(厳密にはHiveQLというSQLに近い言語)を使用してHDFS (Hadoop Distributed File System)のデータを集計・分析することを可能にするソフトウェアです。HDFSは複数のコンピューターのハードディスクを一つのストレージのように扱えるスケーラブルな分散型ファイルシステムであり、大規模なデータを格納できますが、データ集計を行う際MapReduceジョブ(各コンピューターに分割された大量のデータを分散処理するためのフレームワーク)を自身で定義(プログラミング)しなければなりません。そこで開発されたのがHiveで、MapReduceの知識がなくてもHiveQLというSQLライクな言語でHadoop上のデータを解析できます!</p> <p>HiveQLはSQLをベースにしているものの、フルサポートしているわけではないため、一部使用できない構文もあるようです。以下のページにHiveQLの言語レファレンスがございます。</p> <p>Ref: <a href="https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF">https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF</a></p> <h1 id="MIMEエンコードについて">MIMEエンコードについて</h1> <p>MIMEとは、規格上ASCII(7bit文字)のテキストしか使用できないインターネットの電子メールでさまざまなフォーマット(書式)を扱えるようにする規格です。日本語などnon-ASCIIの文字も、MIMEエンコードしASCII文字に変換することでメールで使えるようになります。</p> <p>メールヘッダー上にASCII以外の文字列を含める場合は、以下のような形式で指定します。</p> <pre class="wp-block-code"><code>=?文字セット?エンコード方式?エンコードされた文字列?=</code></pre> <p>文字セット(<code>charset</code>)はUTF-8、エンコード方式(<code>Content-Transfer-Encoding</code>)はBase64でエンコードされたSubjectヘッダー(件名)は例えば以下のような文字列になります。</p> <pre class="wp-block-code"><code>Subject: =?UTF-8?B?55m76Yyy44GX44Gf44Oh44O844Or44Ki44OJ44Os44K544KS56K66KqN44GX?= =?UTF-8?B?44Gm44GP44Gg44GV44GE?=</code></pre> <p>今回の例ではこの組み合わせ(<code>=?UTF-8?B?</code>)でエンコードされた文字列をHiveQLを使用してデコードしていきます。</p> <h1 id="メールデコード処理の流れ">メールデコード処理の流れ</h1> <p>全体の流れとしては以下のようになります:</p> <ol><li>元の文字列を「=?UTF-8?B」で区切って分割(<code>split</code>を使用)し、エンコードされた文字列部分を配列に格納する</li><li>配列の各要素のエンコードされた文字列をBinaryに変換(<code>unbase64</code>を使用)する</li><li>Binaryに変換された各要素をデコードしStringに変換(<code>decode</code>を使用)する</li><li>最後に各要素のStringを連結(<code>concat</code>を使用)する</li></ol> <p>以下が上記流れを踏んだ完成形のクエリです:</p> <p>完成形のクエリ</p> <pre><code class="language-sql">select concat( case when length(split(subject,'=\\?UTF-8\\?B\\?')[0])>0 then split(subject,'=\\?UTF-8\\?B\\?')[0] else '' end, case when length(split(subject,'=\\?UTF-8\\?B\\?')[1])>0 then decode(unbase64(split(subject,'=\\?UTF-8\\?B\\?')[1]),'UTF-8') else '' end, case when length(split(subject,'=\\?UTF-8\\?B\\?')[2])>0 then decode(unbase64(split(subject,'=\\?UTF-8\\?B\\?')[2]),'UTF-8') else '' end ) as decoded_subject from email_table </code></pre> <p>次のセクションでどのようにして上記クエリにたどり着いたか解説します。</p> <h1 id="デコードしてみる">デコードしてみる</h1> <p>それでは、実際にMIMEエンコードされたデータを上記のデコードしていきましょう。Hive上にあるテーブル(「email_log」とします)の「subject」というカラムに以下のようなString型のデータが格納されている前提で、上記流れに従ってデコードをします。</p> <pre class="wp-block-code"><code>=?UTF-8?B?55m76Yyy44GX44Gf44Oh44O844Or44Ki44OJ44Os44K544KS56K66KqN44GX?= =?UTF-8?B?44Gm44GP44Gg44GV44GE?=</code></pre> <ol><li>まず<code>split</code>で「=?UTF-8?B?」という文字列で区切って分割します</li></ol> <pre><code class="language-sql">hive> select split(subject,'=\\?UTF-8\\?B\\?') from email_log; +--------------------------------------------------------------------------------------------+ |split(subject, =\?UTF-8\?B\?, -1) | +--------------------------------------------------------------------------------------------+ |[, 55m76Yyy44GX44Gf44Oh44O844Or44Ki44OJ44Os44K544KS56K66KqN44GX?= , 44Gm44GP44Gg44GV44GE?=] | +--------------------------------------------------------------------------------------------+ </code></pre> <ul><li>0番目の要素: Null</li><li>1番目の要素: 55m76Yyy44GX44Gf44Oh44O844Or44Ki44OJ44Os44K544KS56K66KqN44GX?=</li><li>2番目の要素: 44Gm44GP44Gg44GV44GE?=</li></ul> <ol start="2" style="--previous-count: 1"><li>配列の各要素(本例では1要素目と2要素目)にはBase64エンコードされた文字列がセットされているので、<code>unbase64</code>でBase64エンコードされた文字列をBinaryに変換します</li></ol> <pre><code class="language-sql">hive> select unbase64( split(subject,'=\\?UTF-8\\?B\\?')[1] ), unbase64( split(subject,'=\\?UTF-8\\?B\\?')[2] ) from email_log; +----------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ |unbase64(split(subject, =\?UTF-8\?B\?, -1)[1]) |unbase64(split(subject, =\?UTF-8\?B\?, -1)[2]) | +----------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ |[E7 99 BB E9 8C B2 E3 81 97 E3 81 9F E3 83 A1 E3 83 BC E3 83 AB E3 82 A2 E3 83 89 E3 83 AC E3 82 B9 E3 82 92 E7 A2 BA E8 AA 8D E3 81 97]|[E3 81 A6 E3 81 8F E3 81 A0 E3 81 95 E3 81 84] | +----------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ </code></pre> <ol start="3" style="--previous-count: 2"><li><code>decode</code>で(UTF-8をcharsetとして指定)してBinaryをStringへと変換します</li></ol> <pre><code class="language-sql">hive> select decode( unbase64(split(subject,'=\\?UTF-8\\?B\\?')[1]),'UTF-8' ), decode( unbase64(split(subject,'=\\?UTF-8\\?B\\?')[2]),'UTF-8' ) from email_log; +-------------------------------------------------------------+-------------------------------------------------------------+ |decode(unbase64(split(subject, =\?UTF-8\?B\?, -1)[1]), UTF-8)|decode(unbase64(split(subject, =\?UTF-8\?B\?, -1)[2]), UTF-8)| +-------------------------------------------------------------+-------------------------------------------------------------+ |登録したメールアドレスを確認し |てください | +-------------------------------------------------------------+-------------------------------------------------------------+ </code></pre> <ol start="4" style="--previous-count: 3"><li>配列の1要素目と2要素目の文字列(3でMIMEデコードされた状態)を<code>concat</code>で連結します</li></ol> <pre><code class="language-sql">hive> select concat( decode(unbase64(split(subject,'=\\?UTF-8\\?B\\?')[1]),'UTF-8'), decode(unbase64(split(subject,'=\\?UTF-8\\?B\\?')[2]),'UTF-8') ) as decoded_subject from email_log; +------------------------------------------+ |decoded_subject | +------------------------------------------+ |登録したメールアドレスを確認してください | +------------------------------------------+ </code></pre> <p>これでデコードができましたね!</p> <p>ちなみに、実データには以下のような英文字だけでそもそもエンコードされてないデータだったり、</p> <pre class="wp-block-code"><code>Welcome to ABC!</code></pre> <p>以下のように英文字で始まり途中から<code>=?UTF-8?B?</code>でエンコードされているような変化球もありました。</p> <pre class="wp-block-code"><code>ABC =?UTF-8?B?44Gu44Ko44Oz44K/44O844OX44Op44Kk44K644ON44OD?= =?UTF-8?B?44OI44Ov44O844Kv44Gr44GU5Y+C5Yqg44GP44Gg44GV44GE?=</code></pre> <p>このようなデータも考慮し分岐処理を入れると以下のような感じになります(前述の完成形のクエリと同じ)</p> <pre><code class="language-sql">hive> select concat( case when length(split(subject,'=\\?UTF-8\\?B\\?')[0])>0 then split(subject,'=\\?UTF-8\\?B\\?')[0] else '' end, case when length(split(subject,'=\\?UTF-8\\?B\\?')[1])>0 then decode(unbase64(split(subject,'=\\?UTF-8\\?B\\?')[1]),'UTF-8') else '' end, case when length(split(subject,'=\\?UTF-8\\?B\\?')[2])>0 then decode(unbase64(split(subject,'=\\?UTF-8\\?B\\?')[2]),'UTF-8') else '' end ) as decoded_subject from email_log +---------------------------------------------------+ |decoded_subject | +---------------------------------------------------+ |登録したメールアドレスを確認してください | |Welcome to ABC! | |ABC のエンタープライズネットワークにご参加ください | +---------------------------------------------------+ </code></pre> <p>※0番目の要素は<code>=?UTF-8?B?</code>で始まらない、エンコードされてない文字列なのでデコード処理は不要</p> <p>ちなみに、上記クエリは<code>=?UTF-8?B?</code>で区切られた要素数が最大3個までという前提になってます。もし件名が長い場合は要素数が3より多くなり、クエリで返される文字列が途切れたものになってしまいます。その場合は、以下のようにN番目の要素までクエリを拡張する必要があります。</p> <pre><code class="language-sql">select concat( case when length(split(subject,'=\\?UTF-8\\?B\\?')[0])>0 then split(subject,'=\\?UTF-8\\?B\\?')[0] else '' end, case when length(split(subject,'=\\?UTF-8\\?B\\?')[1])>0 then decode(unbase64(split(subject,'=\\?UTF-8\\?B\\?')[1]),'UTF-8') else '' end, case when length(split(subject,'=\\?UTF-8\\?B\\?')[2])>0 then decode(unbase64(split(subject,'=\\?UTF-8\\?B\\?')[2]),'UTF-8') else '' end, case when length(split(subject,'=\\?UTF-8\\?B\\?')[3])>0 then decode(unbase64(split(subject,'=\\?UTF-8\\?B\\?')[3]),'UTF-8') else '' end, ... case when length(split(subject,'=\\?UTF-8\\?B\\?')[N])>0 then decode(unbase64(split(subject,'=\\?UTF-8\\?B\\?')[N]),'UTF-8') else '' end ) as decoded_subject from email_table </code></pre> <p>可変長にするクエリが思いつきませんでした。可変長にするいいアイデアがあれば教えてほしいですorz</p> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Box CLIの通信をキャプチャーしてみる]]></title><description><![CDATA[Box CLIでコマンドを叩いた際に発生する通信の中身が見たい時、FiddlerのようなHTTPプロキシとして動作する通信デバッグ系のアプリを経由させることによってリクエスト・レスポンスの内容が確認できます。本稿では、設定手順につき記載します。 前提 以下の環境で動かしてます * Box CLI: ver 2.6.0(2.xであれば、きっとこちらの手順でいけると思います) * Fiddler: v5.0.20204.45441 * OS: Windows 10(Mac用のコマンドもちょいちょい記載してますが、未検証です) Fiddler側の設定 Fiddlerを起動して以下の操作を行います。 1. [Tools] > [Options] と遷移し [Options] ダイアログを開く 2. [HTTPS]のタブを開き、[Capture HTTPS CONNECTs] と [Decrypt HTTP traffic]のチェックを有効化する 3. [Actions]をクリックし、[Export Root Certificate to Deskt]]></description><link>https://jikoblog.netlify.app/box-cli-debug-with-fiddler/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3ea</guid><category><![CDATA[Box]]></category><category><![CDATA[Fiddler]]></category><category><![CDATA[Proxy]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Tue, 30 Mar 2021 22:28:22 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1L2S8ix-W8B5mmT8bck89R4-x3hNUjDLZ" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1L2S8ix-W8B5mmT8bck89R4-x3hNUjDLZ" alt="Box CLIの通信をキャプチャーしてみる"/><p>Box CLIでコマンドを叩いた際に発生する通信の中身が見たい時、FiddlerのようなHTTPプロキシとして動作する通信デバッグ系のアプリを経由させることによってリクエスト・レスポンスの内容が確認できます。本稿では、設定手順につき記載します。</p> <h1 id="前提">前提</h1> <p>以下の環境で動かしてます</p> <ul><li>Box CLI: ver 2.6.0(2.xであれば、きっとこちらの手順でいけると思います)</li><li>Fiddler: v5.0.20204.45441</li><li>OS: Windows 10(Mac用のコマンドもちょいちょい記載してますが、未検証です)</li></ul> <h1 id="Fiddler側の設定">Fiddler側の設定</h1> <p>Fiddlerを起動して以下の操作を行います。</p> <ol><li>[Tools] > [Options] と遷移し [Options] ダイアログを開く</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1FH2i8fH8c5gn9SLPs3hzetZ3J9tCdooR" alt="Box CLIの通信をキャプチャーしてみる" class="wp-image-485"/></figure> <ol start="2" style="--previous-count: 1"><li>[HTTPS]のタブを開き、[Capture HTTPS CONNECTs] と [Decrypt HTTP traffic]のチェックを有効化する</li><li>[Actions]をクリックし、[Export Root Certificate to Desktop]を選択する(これによって作成されるFiddlerのルート証明書「FiddlerRoot.cer」は後述の手順で使用します)</li><li>[Connections]タブを開き、[Fiddler listens on port:]に記載されているポート番号を控えておく(デフォはおそらく8888)</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1g4gNbP20s-jL0dkdFmG6btvcx5QrLeAX" alt="Box CLIの通信をキャプチャーしてみる" class="wp-image-488"/></figure> <p>以上で、Fiddler側の設定は完了です。</p> <h1 id="Box CLI側の設定">Box CLI側の設定</h1> <p>Box CLI側でプロキシを設定します。<a rel="noopener" href="https://github.com/box/boxcli/releases/tag/v2.6.0" target="_blank">GitHubのリリースノート</a>によると、Box CLI ver2.6.0からプロキシ対応が導入されたため、こちら以降のバージョンをご利用の場合は、以下のコマンドから使用するプロキシサーバーを指定できます。</p> <pre class="wp-block-code bash"><code>box configure:settings --proxy-url=https://your_proxy_server:proxy_port</code></pre> <p>今回の例では、ローカルホスト(127.0.0.1)で起動しているFiddler(↑の手順#4のポート番号でListen中)をプロキシとして指定するので、以下のように指定します:</p> <pre class="wp-block-code bash"><code>box configure:settings --proxy-url=http://127.0.0.1:8888</code></pre> <p>ちなみに、以下のコマンドでプロキシのオン・オフが切り替えられます(上の行がオフ、下の行がオン)</p> <pre class="wp-block-code bash"><code>box configure:settings --no-enable-proxy box configure:settings --enable-proxy</code></pre> <p>なお、Box CLIのバージョンが古い場合は、Windowsでは以下のコマンドで環境変数を設定することで、プロキシ設定を行えます:</p> <div class="wp-block-cocoon-blocks-caption-box-1 caption-box block-box"><div class="caption-box-label block-box-label box-label"><span class="caption-box-label-text block-box-label-text box-label-text">Windows (CMD)</span></div><div class="caption-box-content block-box-content box-content"> <pre class="wp-block-code bash"><code>set https_proxy=http://127.0.0.1:8888</code></pre> <p/> </div></div> <div class="wp-block-cocoon-blocks-caption-box-1 caption-box block-box"><div class="caption-box-label block-box-label box-label"><span class="caption-box-label-text block-box-label-text box-label-text">Windows (Powershell)</span></div><div class="caption-box-content block-box-content box-content"> <pre class="wp-block-code bash"><code>$env:https_proxy="http://127.0.0.1:8888"</code></pre> <p/> </div></div> <div class="wp-block-cocoon-blocks-caption-box-1 caption-box block-box"><div class="caption-box-label block-box-label box-label"><span class="caption-box-label-text block-box-label-text box-label-text">Mac</span></div><div class="caption-box-content block-box-content box-content"> <pre class="wp-block-code bash"><code>export https_proxy=http://127.0.0.1:8888</code></pre> <p/> </div></div> <p>ここまで設定すると、Box CLIの通信をFiddler経由で行えるようになります。が、この状態でBox CLIのコマンドを叩くと、きっと以下のエラーになります。</p> <pre class="wp-block-code bash"><code>C:\Users\user>box users:get me unable to verify the first certificate</code></pre> <p>証明書エラーですね。そこで、次の手順が必要になります。</p> <h1 id="Fiddlerの証明書を信頼する">Fiddlerの証明書を信頼する</h1> <p>FiddlerでHTTPS通信を復号するにあたり、Fiddlerのルート証明書を信頼する必要があります。Box CLIはNode.jsをベースにしているため、<code>NODE_EXTRA_CA_CERTS</code>という環境変数を指定することで信頼するルート証明書を追加できるようです。</p> <p>なお、<code>NODE_EXTRA_CA_CERTS</code>には、プロキシの認証局 (CA) 証明書 (pem 形式) のファイルの場所を設定する必要があるようで、以下のコマンドで↑の手順#3で作成したFiddlerRoot.cerをpemへと変換します。</p> <pre class="wp-block-code bash"><code>openssl x509 -inform der -in FiddlerRoot.cer -out FiddlerRoot.pem</code></pre> <p>※WindowsにはOpenSSLが標準インストールされてないため、未インストールの場合はインストールが必要になります。<a rel="noopener" href="https://www.atmarkit.co.jp/ait/articles/1601/29/news043.html" target="_blank">こちら</a>のサイトなどが参考になると思います。</p> <p>その後、以下のコマンドでpemの保存場所を<code>NODE_EXTRA_CA_CERTS</code>にセットします</p> <div class="wp-block-cocoon-blocks-caption-box-1 caption-box block-box"><div class="caption-box-label block-box-label box-label"><span class="caption-box-label-text block-box-label-text box-label-text">Windows</span></div><div class="caption-box-content block-box-content box-content"> <pre class="wp-block-code bash"><code>set NODE_EXTRA_CA_CERTS=C:\path\to\FiddlerRoot.pem</code></pre> </div></div> <div class="wp-block-cocoon-blocks-caption-box-1 caption-box block-box"><div class="caption-box-label block-box-label box-label"><span class="caption-box-label-text block-box-label-text box-label-text">Windows (Powershell)</span></div><div class="caption-box-content block-box-content box-content"> <pre class="wp-block-code bash"><code>$env:NODE_EXTRA_CA_CERTS=C:\path\to\FiddlerRoot.pem</code></pre> </div></div> <div class="wp-block-cocoon-blocks-caption-box-1 caption-box block-box"><div class="caption-box-label block-box-label box-label"><span class="caption-box-label-text block-box-label-text box-label-text">Mac</span></div><div class="caption-box-content block-box-content box-content"> <pre class="wp-block-code bash"><code>export NODE_EXTRA_CA_CERTS=/path/to/FiddlerRoot.pem</code></pre> </div></div> <p>なお、Windowsの<code>SET</code>コマンドで指定した環境変数はそのセッションのみ有効となるため、コマンドプロンプトを別のウィンドウで開く際は再度設定が必要になります。設定を保持する場合は、以下のように環境変数を追加することで可能となります。</p> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1iOfqZr_ZkrWqxBMzSO5VCYnJ09Tg9yRd" alt="Box CLIの通信をキャプチャーしてみる" class="wp-image-486"/></figure> <h1 id="Box CLIをFiddler経由で実行する">Box CLIをFiddler経由で実行する</h1> <p>それでは、Box CLIでコマンドを叩いてみます。</p> <pre><code class="language-bash">C:\Users\user> box users:get me Type: user ID: '12345678' Name: CLITest Login: AutomationUser_123456_abcdefg@boxdevedition.com Created At: '2018-08-13T20:26:19-07:00' Modified At: '2020-03-11T01:15:34-07:00' Language: en Timezone: Asia/Tokyo Space Amount: 10737418240 Space Used: 0 Max Upload Size: 16106127360 Status: active Job Title: '' Phone: '' Address: '' Avatar URL: 'https://app.box.com/api/avatar/large/12345678' Notification Email: [] </code></pre> <p>Fiddlerでリクエスト・レスポンスの中身が見えていればOKです。これで通信のデバッグができますね!</p> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=15nn0yW8cq148k4z0f32e2OU9dKEqq1Wu" alt="Box CLIの通信をキャプチャーしてみる" class="wp-image-487"/></figure> <h1 id="参考文献">参考文献</h1> <ul><li><a rel="noopener" href="https://github.com/box/boxcli" target="_blank">https://github.com/box/boxcli</a></li><li><a rel="noopener" href="https://medium.com/box-developer-blog/box-cli-adds-proxy-support-b67e930cf614" target="_blank">https://medium.com/box-developer-blog/box-cli-adds-proxy-support-b67e930cf614</a></li></ul> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Box + Microsoft Intune MAM without Enrollment を設定してみた]]></title><description><![CDATA[Box + Microsoft Intune MAM without Enrollment を設定してみました。手順や注意点を記載します。 ※公式の資料があまり見つからず、個人的な見解も多少混じってますので、間違い等ございましたら、ご指摘いただけますと幸いです。 Box + Microsoft Intune MAM without Enrollment とは もともとBoxは「Box for EMM」というMDM連携用のアプリを提供していたようですが、「Box for EMM」はMDMへ登録済みのデバイス上でしか(with Enrollmentでしか)利用ができませんでした。 それが以下のリリースノートによると、Intune MAM without Enrollmentに対応したとのことで、MDMへデバイスを登録せずに(without Enrollmentで)、BoxアプリをIntuneの管理下とする(Intune MAMのアプリ保護ポリシーの対象とする)ことが可能になったようです。 https://support.box.com/hc/ja/articles/360]]></description><link>https://jikoblog.netlify.app/box-microsoft-intune-mam-without-enrollment/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3e9</guid><category><![CDATA[Box]]></category><category><![CDATA[Intune]]></category><category><![CDATA[モバイル]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Mon, 22 Feb 2021 07:50:10 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1bOJ0eIkwxPii3DOJ4XXcvZ9U-oWCQNAb" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1bOJ0eIkwxPii3DOJ4XXcvZ9U-oWCQNAb" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた"/><p>Box + Microsoft Intune MAM without Enrollment を設定してみました。手順や注意点を記載します。<br>※公式の資料があまり見つからず、個人的な見解も多少混じってますので、間違い等ございましたら、ご指摘いただけますと幸いです。</br></p> <h1 id="Box + Microsoft Intune MAM without Enrollment とは">Box + Microsoft Intune MAM without Enrollment とは</h1> <p>もともとBoxは「<a rel="noopener" href="https://support.box.com/hc/ja/articles/360043694974-Box-for-EMM%E3%81%AE%E6%A6%82%E8%A6%81%E3%81%A8FAQ" target="_blank">Box for EMM</a>」というMDM連携用のアプリを提供していたようですが、「Box for EMM」はMDMへ登録済みのデバイス上でしか(with Enrollmentでしか)利用ができませんでした。</p> <p>それが以下のリリースノートによると、Intune MAM without Enrollmentに対応したとのことで、MDMへデバイスを登録せずに(without Enrollmentで)、BoxアプリをIntuneの管理下とする(Intune MAMのアプリ保護ポリシーの対象とする)ことが可能になったようです。</p> <p><a rel="noopener" href="https://support.box.com/hc/ja/articles/360057142753-AndroidおよびiOS向けIntune-MAM-without-Enrollment" target="_blank">https://support.box.com/hc/ja/articles/360057142753-AndroidおよびiOS向けIntune-MAM-without-Enrollment</a></p> <p>MDMの管理下へデバイスを登録するということは、MDM管理者がデバイスに対してリモートロックやリモートワイプといった操作がかけられるということになるので、個人が所有しているデバイスを業務で活用するBYODでの利用はハードルが高いと思います(誰だって勝手に初期化されかねない状況に自分のデバイスを置きたくないですよね)。</p> <p>Intune MAM without Enrollmentでは、MDMにデバイスを登録せずにMAMのアプリ保護機能を使えるので、企業に関連するアプリのみMAMで制限をかけ、プライベート領域と切り離して管理ができます。よって、BYODに向いているといえるのだと思います。</p> <p>それでは、設定手順に移りたいと思います。</p> <h1 id="Microsoft Intune側の設定">Microsoft Intune側の設定</h1> <p>まず、<a rel="noopener" href="https://endpoint.microsoft.com/" target="_blank">Microsoft Endpoint Manager</a>からIntune MAM機能をモバイルアプリ(Box)に対して有効化する設定を行います。以下のMicrosoft社のドキュメント通りに設定を行います。<a rel="noopener" href="https://docs.microsoft.com/ja-jp/mem/intune/apps/app-protection-policies#create-an-iosipados-or-android-app-protection-policy" target="_blank">https://docs.microsoft.com/ja-jp/mem/intune/apps/app-protection-policies#create-an-iosipados-or-android-app-protection-policy</a></p> <ol><li><a href="https://go.microsoft.com/fwlink/?linkid=2109431">Microsoft Endpoint Manager 管理センター</a>にサインインする。</li><li>[アプリ] > [アプリ保護ポリシー]と遷移し、[ポリシーの作成]をクリックする。</li><li>ポリシーの対象とするOSを選択する。iOSの場合は[iOS/iPadOS]、Androidの場合は[Android]を選択する。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1TtyoaA_BXRj6zSTj-DG6Z9JCvxaB-KPy" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-454"/></figure> <ol start="4" style="--previous-count: 3"><li>[ポリシーの作成]ウィンドウが開かれるので、ポリシーに任意の名前を付ける。</li><li>[アプリ]にて[パブリックアプリの選択]より[Box – Cloud Content Management]を選択する。<br>※[Box for EMM]を選ばないこと!</br></li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1DVSLv7PvdALEYxolbzq9oLb3mX6TUKvI" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-455"/></figure> <ol start="6" style="--previous-count: 5"><li>[データ保護]、[アクセス要件]、[条件付き起動]を以下の記事を参考に自身の要件に沿って設定する。</li></ol> <ul><li>iOS/iPadOS: <a rel="noopener" href="https://docs.microsoft.com/ja-jp/mem/intune/apps/app-protection-policy-settings-ios" target="_blank">https://docs.microsoft.com/ja-jp/mem/intune/apps/app-protection-policy-settings-ios</a></li><li>Android: <a rel="noopener" href="https://docs.microsoft.com/ja-jp/mem/intune/apps/app-protection-policy-settings-android" target="_blank">https://docs.microsoft.com/ja-jp/mem/intune/apps/app-protection-policy-settings-android</a></li></ul> <ol start="7" style="--previous-count: 6"><li>[割り当て]で、ポリシーの対象とするグループを選択する(ポリシーの対象になっていないユーザーはBoxモバイルアプリにログインできなくなります!)。</li><li>[確認および作成]で、設定の内容をレビューし[作成]を押下してポリシーを保存する。</li></ol> <p>ここまででMicrosoft Intune側の設定は完了です。</p> <h1 id="Box側の設定">Box側の設定</h1> <p>Boxモバイルアプリにユーザーがログインを行う際に、Boxモバイルアプリに対してIntune MAMが適用されるように設定を行います。</p> <ol><li>Box管理者としてログインし管理コンソールを開く。</li><li>[Enterprise設定] > [モバイル] と遷移する。</li><li>[Intuneモバイルアプリケーション管理 (Intune MAM) を有効化する]のトグルを有効化する。</li></ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1N4Pkr1_cnHoBcStrzM9ijnJND5fnp1Nn" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-456"/></figure> <p>Box側の設定は以上です。上記設定を行うことで、所属ユーザーがBoxモバイルアプリでログインを行う際に、Intune MAMへのEnrollを促す画面へと遷移する動作となるようです。</p> <h1 id="iOS/iPadOSでBoxを使ってみる">iOS/iPadOSでBoxを使ってみる</h1> <p>iPhone(MDMに未登録)にてアプリストアからBoxをインストールしてログインしてみます。</p> <figure class="wp-block-image size-large is-resized"> <img loading="lazy" src="https://docs.google.com/uc?id=1z0muMZ90w6d3gWq1NOIQDihyuCbGT6w5" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-457" width="320" height="568"/> </figure> <p>ログイン画面よりBoxアカウントで認証を完了すると、以下のような画面が表示されます。</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1LyrnUdcWeOXBub2dI0jA_bC_29IqzvuV" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-458" width="320" height="568"/></figure> <p>[Enroll in Intune MAM]を選択すると、Microsoftアカウントの認証ページに飛ばされます。</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1U1khCAQYZRNVfxHEiQvkmsbKhsCsmP38" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-459" width="320" height="568"/></figure> <p>Microsoftアカウントで認証を済ませると、Boxモバイルアプリが組織によって管理されている旨のメッセージが表示されアプリの再起動を促されます。</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1rh7BcdWSErEVypd9Tqk8R_QRyfoFYkzT" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-460" width="320" height="568"/></figure> <p>これでiPhoneをMDMに登録することなく、BoxモバイルアプリだけをIntuneの管理下とすることができました!</p> <h1 id="AndroidでBoxを使ってみる">AndroidでBoxを使ってみる</h1> <p>Android(MDMに未登録)にてGoogle Play ストアからBoxをインストールしてログインしてみます。</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1NnymaiXNvVRIQ4IwbAgRvso7LZXVm8mR" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-463" width="270" height="480"/></figure> <p>ログイン画面よりBoxアカウントで認証を完了すると、Google Playストアが開き[Intune Company Portal]アプリをインストールするよう促されます。</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1kk2SWOElesv--3YpUqOCW5a2shjZhrHb" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-464" width="270" height="480"/></figure> <p>[Intune Company Portal]アプリをインストール後、Boxアプリを開きなおすと、Microsoftアカウントで認証するよう促されます。<br>※[Intune Company Portal]アプリ内でのログインは不要です(ただインストールすることは必須だそうです。Ref: <a rel="noopener" href="https://docs.microsoft.com/ja-jp/mem/intune/apps/mam-faq#app-experience-on-android" target="_blank">https://docs.microsoft.com/ja-jp/mem/intune/apps/mam-faq#app-experience-on-android</a>)</br></p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1ucOej8prYbh_guX1tXOycIVE6IGF3l0q" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-465" width="270" height="480"/></figure> <p>Microsoftアカウントで認証後、以下のような画面になりBoxアプリがIntuneの管理下となっていることがわかります。</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1zI1F4FJCO8IDE8z_4aI6B9PcdJm2k2I1" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-467" width="270" height="480"/></figure> <h1 id="注意点">注意点</h1> <p>Boxへのログインに使用するアカウントのメールアドレスとMicrosoft Intune側のアカウントのメールアドレスは一致していないとログインができないようです。異なるメールアドレスを使用した場合、Intuneアカウントでログインしようとした際にエラーになりました。</p> <div class="wp-block-cocoon-blocks-caption-box-1 caption-box block-box"><div class="caption-box-label block-box-label box-label"><span class="caption-box-label-text block-box-label-text box-label-text">iOSのエラー</span></div><div class="caption-box-content block-box-content box-content"> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1PrFpI-RDqUXbbViXkAJiyNE7kVxh85Zp" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-462" width="320" height="568"/></figure> </div></div> <div class="wp-block-cocoon-blocks-caption-box-1 caption-box block-box"> <div class="caption-box-label block-box-label box-label"> <span class="caption-box-label-text block-box-label-text box-label-text">Androidのエラー</span> </div> <div class="caption-box-content block-box-content box-content"> <figure class="wp-block-image size-large is-resized"> <img loading="lazy" src="https://docs.google.com/uc?id=1tSWjziynKo-8I4ZjDRZzGRuVeJ0mM6qf" alt="Box + Microsoft Intune MAM without Enrollment を設定してみた" class="wp-image-466" width="270" height="480"/> </figure> </div> </div><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Googleモバイルフレンドリーテストで表示が崩れる]]></title><description><![CDATA[スマホでページを閲覧するときは問題ないのに、Googleのモバイルフレンドリーテストでページをレンダリングするときはなぜか表示が崩れて、モバイルフレンドリーテストがFailしてました。解決方法につき記載します。 事象 Googleのモバイルフレンドリーテストはモバイルデバイスでのページの使いやすさをテストするツールです。昨今よりGoogleではスマートフォンクローラが使用されているようで、このテストがこけているとSEOで検索下位に表示されたり、無視されてインデックスすらされないこともあるようで、非常に重要な問題です。 モバイル端末からページを開く際に表示が崩れてなければ特に問題ないと思ってました。が、なぜかモバイルフレンドリーテストがFailしてました。テストだと以下のようにページがレンダリングされており、確かに表示が崩れております。 でも、スマホで見ると特に問題はないのです。はて??? 原因 「ページの読み込みに関する問題」の「詳細を表示」すると原因が見えてきました。どうやらスタイリングに使用するcssやjsといったスタティックアセットがテストの際に読]]></description><link>https://jikoblog.netlify.app/google-mobile-friendly-test/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3e8</guid><category><![CDATA[WordPress]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Tue, 22 Dec 2020 06:36:58 GMT</pubDate><media:content url="https://docs.google.com/uc?id=12n1bS2LcvVQ8pNh3x3_yOzcNC7Mj_Fsl" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=12n1bS2LcvVQ8pNh3x3_yOzcNC7Mj_Fsl" alt="Googleモバイルフレンドリーテストで表示が崩れる"/><p>スマホでページを閲覧するときは問題ないのに、Googleのモバイルフレンドリーテストでページをレンダリングするときはなぜか表示が崩れて、モバイルフレンドリーテストがFailしてました。解決方法につき記載します。</p> <h1 id="事象">事象</h1> <p>Googleの<a rel="noopener" href="https://search.google.com/test/mobile-friendly" target="_blank">モバイルフレンドリーテスト</a>はモバイルデバイスでのページの使いやすさをテストするツールです。昨今よりGoogleでは<a rel="noopener" href="https://developers.google.com/search/docs/advanced/crawling/googlebot?hl=ja" target="_blank">スマートフォンクローラ</a>が使用されているようで、このテストがこけているとSEOで検索下位に表示されたり、無視されてインデックスすらされないこともあるようで、非常に重要な問題です。</p> <p>モバイル端末からページを開く際に表示が崩れてなければ特に問題ないと思ってました。が、なぜかモバイルフレンドリーテストがFailしてました。テストだと以下のようにページがレンダリングされており、確かに表示が崩れております。</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1-VSKaHSN5nPfnLbusQJ4iH4pIp6ZlakB" alt="Googleモバイルフレンドリーテストで表示が崩れる" class="wp-image-445" width="358" height="687"/><figcaption>Googleモバイルフレンドリーテストを実行時</figcaption></figure> <p>でも、スマホで見ると特に問題はないのです。はて???</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1MPc5KpIVS83ybustp55ADKLreqZrMGQY" alt="Googleモバイルフレンドリーテストで表示が崩れる" class="wp-image-437" width="357" height="634"/><figcaption>スマホから閲覧した場合</figcaption></figure> <h1 id="原因">原因</h1> <p>「ページの読み込みに関する問題」の「詳細を表示」すると原因が見えてきました。どうやらスタイリングに使用する<code>css</code>や<code>js</code>といったスタティックアセットがテストの際に読み込まれてなかったようです。</p> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=18SUg9fq3VyfQ3mhNvK_1WZQrzl2HU22Y" alt="Googleモバイルフレンドリーテストで表示が崩れる" class="wp-image-448"/></figure> <p>ステータスの列に「Googlebotがrobots.txtによってブロックされています」と記載されております。<code>robots.txt</code>とは、サイト内でクローラ(Googleなどサーチエンジンの)に収集されたくないコンテンツを指定できるファイルです。私の場合は、以下のように記述しておりました。</p> <div class="wp-block-cocoon-blocks-caption-box-1 caption-box block-box"><div class="caption-box-label block-box-label box-label"><span class="caption-box-label-text block-box-label-text box-label-text">robots.txt</span></div><div class="caption-box-content block-box-content box-content"> <pre class="wp-block-code"><code># global User-agent: * Disallow: /cgi-bin/ Disallow: /wp/wp-admin/ Disallow: /wp/wp-includes/ Disallow: /app/plugins/ Disallow: /app/mu-plugins/ Disallow: /app/cache/ Disallow: /app/themes/ Allow: /app/uploads/</code></pre> </div></div> <p>WordPressで使用しているテーマの<code>css</code>や<code>js</code>が格納されている<code>/app/plugins/</code>配下がクロールの<code>Disallow</code>(禁止)対象とする記述になっておりました。</p> <p>よって、モバイル端末から閲覧した際には問題がないものの、モバイルフレンドリーテスト(クローラ)がアクセスしたときだけ表示崩れが発生しておりました。</p> <h1 id="解決方法">解決方法</h1> <p>以下を<code>robots.txt</code>に追記することで解決しました。</p> <pre class="wp-block-code"><code>User-Agent: Googlebot Allow: .js Allow: .css</code></pre> <p>Googlebotに対しては、<code>.js</code>と<code>.css</code>はどこのパスにあってもクロールを<code>Allow</code>(許可)するという指定方法です。</p> <div class="gatsby-code-title"><span>robots.txt(変更後)</span></div> <pre><code class="language-none"># global User-agent: * Disallow: /cgi-bin/ Disallow: /wp/wp-admin/ Disallow: /wp/wp-includes/ Disallow: /app/plugins/ Disallow: /app/mu-plugins/ Disallow: /app/cache/ Disallow: /app/themes/ Allow: /app/uploads/ # For allowing access to site from mobile friendly test User-Agent: Googlebot Allow: .js Allow: .css </code></pre> <p>上記にて自身のサーバー上の<code>robots.txt</code>を更新した後、Googleの<a rel="noopener" href="https://www.google.com/webmasters/tools/robots-testing-tool" target="_blank">robots.txtテスターツール</a>を開き「送信」を押し更新をGoogleに通知することで、Googleに最新の<code>robots.txt</code>を取得してもらいます。</p> <p>その後、先ほどモバイルフレンドリーではありませんと判定されたページを再びモバイルフレンドリーテストにかけると、無事Passすることができました!</p> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[WordPressをDocker上でWP-CLIで実行する]]></title><description><![CDATA[WordPressのローカル開発環境の手段として、WP-CLI(WordPressを管理するためのコマンドラインツール)をDocker Desktop上で実行しWordPressを動かす方法を取ってみました。手順を書き残しておきます。 利用環境 私が利用した開発環境は以下になります。 * Windows 10(WordPressはDocker上で動かすのでホストOS依存しないと思います) * wordpress-herokuのプロジェクトを利用 ※wordpress-herokuとはBedrockをベースにしたWordPressをHeroku上で動かすことを楽ちんにしてくれるプロジェクトです。 この手法を取った背景 そもそもwordpress-herokuプロジェクトはローカル環境でもWordPressを動かすための手順を用意しており、こちらのWikiに記載されております。 にもかかわらず、なぜわざわざDocker上で動かすのかというと、RedisやMySQLもローカル用に環境を用意したいってなった時に楽そうかな、と思ったのがまず一点。 そして、]]></description><link>https://jikoblog.netlify.app/wordpress-wp-cli/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3e7</guid><category><![CDATA[WordPress]]></category><category><![CDATA[Heroku]]></category><category><![CDATA[Docker]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Mon, 14 Dec 2020 07:57:53 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1cstzCmZOSgtdLl-2mT7jFzfnrr8VJOtu" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1cstzCmZOSgtdLl-2mT7jFzfnrr8VJOtu" alt="WordPressをDocker上でWP-CLIで実行する"/><p>WordPressのローカル開発環境の手段として、WP-CLI(WordPressを管理するためのコマンドラインツール)をDocker Desktop上で実行しWordPressを動かす方法を取ってみました。手順を書き残しておきます。</p> <h1 id="利用環境">利用環境</h1> <p>私が利用した開発環境は以下になります。</p> <ul> <li>Windows 10(WordPressはDocker上で動かすのでホストOS依存しないと思います)</li> <li><a href="https://github.com/PhilippHeuer/wordpress-heroku">wordpress-heroku</a>のプロジェクトを利用</li> </ul> <p>※<a href="https://github.com/PhilippHeuer/wordpress-heroku">wordpress-heroku</a>とは<a href="https://roots.io/bedrock/">Bedrock</a>をベースにしたWordPressをHeroku上で動かすことを楽ちんにしてくれるプロジェクトです。</p> <h1 id="この手法を取った背景">この手法を取った背景</h1> <p>そもそも<a href="https://github.com/PhilippHeuer/wordpress-heroku">wordpress-heroku</a>プロジェクトはローカル環境でもWordPressを動かすための手順を用意しており、<a rel="noopener" href="https://github.com/PhilippHeuer/wordpress-heroku/wiki/Deployment#deployment---local" target="_blank">こちら</a>のWikiに記載されております。</p> <p>にもかかわらず、なぜわざわざDocker上で動かすのかというと、RedisやMySQLもローカル用に環境を用意したいってなった時に楽そうかな、と思ったのがまず一点。</p> <p>そして、大きな理由としては、Windows上で手順通りにWordPressを動かしてみた(以下のコマンドを実行)ものの、なんか動作が怪しかったという。。。</p> <pre><code class="language-bash">php wp-cli.phar server --host=0.0.0.0 --port=80 --path=web </code></pre> <p>自身で追加したテーマが使われずデフォのTwenty-Seventeenっぽいテーマが使用されてたり。。</p> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1U8ruExWYMk_Lfbqj6ZEChju3X4aEdNR4" alt="WordPressをDocker上でWP-CLIで実行する" class="wp-image-396" width="714" height="447"/></figure> <p>サーバーログにも特に関連がありそうなエラーも見つからず、コードを深く追うことも避けたかったため、実行環境(Windows)の問題なのかな、とDockerで動かしてみたらなんと諸々問題が解消されました!</p> <h1 id="セットアップ方法">セットアップ方法</h1> <p>さて、前置きが長くなりましたが、セットアップに移りましょう。</p> <p><code>wp-cli</code>のDocker用のイメージ(<a rel="noopener" href="https://make.wordpress.org/cli/handbook/guides/installing/#installing-via-docker" target="_blank"><code>wordpress:cli</code></a>)が配布されており、そちらを使用してWordPressをDocker上で動かします。</p> <p>手順は以下になります。</p> <ol><li>Docker Desktopをインストールします。</li></ol> <p>URL: <a rel="noopener" href="https://docs.docker.jp/get-docker.html" target="_blank">https://docs.docker.jp/get-docker.html</a><br>※インストール手順はWeb上の各所で記載されており、ここでは割愛します。</br></p> <ol start="2" style="--previous-count: 1"><li>プロジェクトフォルダの直下に<code>docker-compose.yml</code>を作成します。</li></ol> <div class="gatsby-code-title">docker-compose.yml</div> <pre><code class="language-yml">version: '3.6' services: cli: image: wordpress:cli-2.4.0-php7.4 volumes: - .:/var/www/html ports: - "80:8080" envlog_file: .env command: wp server --host=0.0.0.0 --port=8080 --path=web </code></pre> <ol start="3" style="--previous-count: 2"><li>その後、Dockerを起動した状態で、コマンドプロンプトにて以下のコマンド実行しDockerコンテナが稼働するIPアドレスを確認します。</li></ol> <pre><code class="language-docker">docker-machine ip </code></pre> <ol start="4" style="--previous-count: 3"><li>私の場合は192.168.99.100が返ってきました。そのIPアドレスをプロジェクトフォルダ内の<code>.env</code>ファイルに記載します。</li></ol> <div class="gatsby-code-title">.env(変更前)</div> <pre><code>WP_HOME=http://localhost WP_SITEURL=${WP_HOME}/wp </code></pre> <div class="gatsby-code-title">.env(変更後)</div> <pre><code>WP_HOME=http://192.168.99.100 WP_SITEURL=http://192.168.99.100/wp </code></pre> <ol start="5" style="--previous-count: 4"><li>コマンドプロンプトでプロジェクトフォルダに移動して、以下のコマンドを実行してコンテナをビルドおよび実行します。</li></ol> <pre><code class="language-docker">docker-compose up </code></pre> <ol start="6" style="--previous-count: 5"><li>これで準備完了です。Dockerコンテナにhttpでアクセスしてページを開くことができます。</li></ol> <p><a href="http://192.168.99.100">http://192.168.99.100</a></p> <h1 id="Appendix">Appendix</h1> <p><code>docker-compose.yml</code>の補足的な説明を書き残しときます。</p> <ul> <li>image: 現時点で一番新しそうな<code>wordpress:cli-2.4.0-php7.4</code>を使用してます。</li> <li>volumes: <code>.:/var/www/html</code>と指定し、ホスト側のカレントディレクトリ(プロジェクトフォルダ)をコンテナ側に共有します。これにより、コンテナ側からホスト側にあるWordPressのプロジェクトフォルダにアクセスできます。</li> <li>ports: 外部(コンテナ外)からは80番ポートで接続できるように、8080を80へマッピングしてます。</li> <li>env_file: <a href="https://github.com/PhilippHeuer/wordpress-heroku/wiki/Deployment#deployment---local">こちら</a>の手順通り<code>.env</code>ファイルを作成し、それが参照されます。</li> <li>command: <a rel="noopener" href="https://developer.wordpress.org/cli/commands/server/" target="_blank"><code>wp server</code></a>コマンドを<code>port=8080</code>で指定して実行してます。<code>port=80</code>でやろうとしたら以下のエラーになったので、80以外で指定が必要なのだと思います。</li> </ul> <pre><code class="language-log">cli_1 | [Sun Dec 13 12:30:30 2020] Failed to listen on 0.0.0.0:80 (reason: Permission denied) </code></pre> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Herokuで"at=error code=H14 desc=No web processes running"エラーになる件]]></title><description><![CDATA[HerokuにDockerコンテナ(Webサーバー)をデプロイした際に、"No web processes running"エラーが発生してしまいました。原因や解決方法について調べたので、内容をメモします。 事象 HerokuにDockerコンテナ(Expressを利用したWebサーバー)をデプロイした後、ページを開いてみるとApplication errorが発生しておりました。 サーバーログをheroku logs --tailで確認してみると、以下のように"No web processes running"とのエラーが出力されておりました。 2020-12-06T06:05:22.736018+00:00 heroku[router]: at=error code=H14 desc="No web processes running" method=GET path="/" host=jiko-album-artwork-backend.herokuapp.com request_id=33285f21-ed78-4733-b3d4-1214031f1d]]></description><link>https://jikoblog.netlify.app/heroku-at-error-code-h14-desc-no-web-processes-running/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3e6</guid><category><![CDATA[Heroku]]></category><category><![CDATA[Docker]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Fri, 11 Dec 2020 08:55:23 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1V-TEbFTgFEND6dHiKSoAkNsFMhYS2v5e" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1V-TEbFTgFEND6dHiKSoAkNsFMhYS2v5e" alt="Herokuで"at=error code=H14 desc=No web processes running"エラーになる件"/><p>HerokuにDockerコンテナ(Webサーバー)をデプロイした際に、"No web processes running"エラーが発生してしまいました。原因や解決方法について調べたので、内容をメモします。</p> <h1 id="事象">事象</h1> <p>HerokuにDockerコンテナ(Expressを利用したWebサーバー)をデプロイした後、ページを開いてみるとApplication errorが発生しておりました。</p> <p>サーバーログを<code>heroku logs --tail</code>で確認してみると、以下のように"No web processes running"とのエラーが出力されておりました。</p> <pre><code class="language-log">2020-12-06T06:05:22.736018+00:00 heroku&#91;router]: at=error code=H14 desc="No web processes running" method=GET path="/" host=jiko-album-artwork-backend.herokuapp.com request_id=33285f21-ed78-4733-b3d4-1214031f1daa fwd="118.158.162.21" dyno= connect= service= status=503 bytes= protocol=https 2020-12-06T06:05:23.397411+00:00 heroku&#91;router]: at=error code=H14 desc="No web processes running" method=GET path="/favicon.ico" host=jiko-album-artwork-backend.herokuapp.com request_id=39ff37fc-42c9-4f68-aedf-19c1e3cfcc5c fwd="118.158.162.21" dyno= connect= service= status=503 bytes= protocol=https </code></pre> <h1 id="原因">原因</h1> <p>どうやらDockerコンテナをビルドする際に指定したプロセス名に問題があったようです。</p> <p>私がデプロイに使用したコマンドは次の通りです。</p> <pre><code class="language-docker">docker build -t registry.heroku.com/$HEROKU_BACKEND_APP_NAME/express -f ./express/Dockerfile.express ./express; docker push registry.heroku.com/$HEROKU_BACKEND_APP_NAME/express; heroku container:release express --app $HEROKU_BACKEND_APP_NAME </code></pre> <p><a rel="noopener" href="https://devcenter.heroku.com/articles/container-registry-and-runtime#building-and-pushing-image-s" target="_blank">こちら</a>の記事を読んだ際、Dockerコンテナをデプロイするにあたり、<code><process-type></code>は任意の文字列でいいのかなと思っていたので、”express”を指定しておりました。が、どうやらWebサーバーとして動かすコンテナは”web”と指定しないと動かないようです。</p> <p><a href="https://devcenter.heroku.com/articles/container-registry-and-runtime#building-and-pushing-image-s">こちら</a>の記事を読んだ際、Dockerコンテナをデプロイするにあたり、<code><process-type></code>は任意の文字列でいいのかなと思っていたので、"express"と指定しておりました。が、どうやらWebサーバーとして動かすコンテナは"web"と指定しないと動かないようです。</p> <p>よくよく調べてみると公式ドキュメントの<a href="https://devcenter.heroku.com/articles/dynos#dyno-configurations">別のページ</a>に、Herokuのプロセスタイプは"Web", "Worker", "One-off"の3種類があり、その中でも"Web"プロセスのみが外部から(HerokuのRouterを経由)のHTTPトラフィックを受信できる、と記載されてますね。つまり、"Web"プロセスがなければ、ページにアクセスしてもトラフィックがデプロイしたWebサーバーに届かずにエラーになるようです。</p> <h1 id="解決方法">解決方法</h1> <p>よって、<code><process-type></code>を以下のように"web"で指定することで無事ページが開けるようになりました!</p> <pre><code class="language-docker">docker build -t registry.heroku.com/$HEROKU_BACKEND_APP_NAME/web -f ./express/Dockerfile.express ./express; docker push registry.heroku.com/$HEROKU_BACKEND_APP_NAME/web; heroku container:release web --app $HEROKU_BACKEND_APP_NAME </code></pre> <p>ちなみに、私は上記を実行した後、以下のコマンドも実行してWebプロセスのDynoを手動で立ちあげる必要がありました。</p> <pre><code class="language-bash">heroku ps:scale web=1 </code></pre> <p>上記は"web"のDynoを1というスケールで実行するコマンドです。Dyno<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>の数を増やすことでスケールアウトできます。</p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>DynoとはHerokuで使用されるコンテナのこと。<a href="https://jp.heroku.com/dynos">参考記事</a> <a href="#fnref1" class="footnote-backref">↩︎</a></p> </li> </ol> </section> <!--kg-card-end: markdown--></hr>]]></content:encoded></item><item><title><![CDATA[TypeScriptチートシート]]></title><description><![CDATA[TypeScriptの実行環境の準備 TypeScript を始めるために必要なパッケージをインストールする $ npm install -g typescript ts-node パッケージ概要typescriptTypeScriptコンパイラ(トランスパイラ)ts-nodeTypeScriptのコンパイルと実行を一つのコマンドでできるCLIツール インストール後は、以下のコマンドを実行してインストールされていることを確認する $ tsc --version Version 4.0.3 ※tscは typescript の短縮名 TypeScriptを実行する TypeScript のコードを実行してみる hello.ts function hello(name: string): void { console.log(`Hello ${name}!`); } hello('kojimaru'); 上記ファイルを用意し、以下のコマンドを実行する $ tsc hello.ts するとhello.jsが作成され]]></description><link>https://jikoblog.netlify.app/typescript-cheat-sheet/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3e5</guid><category><![CDATA[TypeScript]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Sun, 06 Dec 2020 13:24:35 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1z6CstZQzHj9QYcgcLMAnYeRgctDLaiRf" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h1 id="TypeScriptの実行環境の準備">TypeScriptの実行環境の準備</h1> <img src="https://docs.google.com/uc?id=1z6CstZQzHj9QYcgcLMAnYeRgctDLaiRf" alt="TypeScriptチートシート"/><p>TypeScript を始めるために必要なパッケージをインストールする</p> <pre><code class="language-bash">$ npm install -g typescript ts-node </code></pre> <figure class="wp-block-table"><table><tbody><tr><td><strong>パッケージ</strong></td><td><strong>概要</strong></td></tr><tr><td>typescript</td><td>TypeScriptコンパイラ(トランスパイラ)</td></tr><tr><td>ts-node</td><td>TypeScriptのコンパイルと実行を一つのコマンドでできるCLIツール</td></tr></tbody></table></figure> <p>インストール後は、以下のコマンドを実行してインストールされていることを確認する</p> <pre><code class="language-bash">$ tsc --version Version 4.0.3 </code></pre> <div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content">※<code>tsc</code>は typescript の短縮名</span></div> <h1 id="TypeScriptを実行する">TypeScriptを実行する</h1> <p>TypeScript のコードを実行してみる</p> <div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box"><div class="tab-caption-box-label block-box-label box-label"><span class="tab-caption-box-label-text block-box-label-text box-label-text">hello.ts</span></div><div class="tab-caption-box-content block-box-content box-content"> <pre class="wp-block-code"><code>function hello(name: string): void { console.log(`Hello ${name}!`); } <p>hello('kojimaru');</p></code></pre> <p/> </div></div> <p>上記ファイルを用意し、以下のコマンドを実行する</p> <pre class="wp-block-code"><code>$ tsc hello.ts</code></pre> <p>すると<code>hello.js</code>が作成される。<code>hello.js</code>は<code>node hello.js</code>で実行できる</p> <pre class="wp-block-code"><code>$ node hello.js Hello kojimaru!</code></pre> <p>もしくは<code>ts-node</code>を使用することで、コンパイルと実行を同時に行える</p> <pre class="wp-block-code"><code>$ ts-node hello.ts Hello kojimaru!</code></pre><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[FiddlerでBasic認証のプロキシ環境を構築する]]></title><description><![CDATA[FiddlerはHTTP/HTTPS通信をキャプチャーするツールとして有名ですが、端末のプロキシサーバーとして使用することができ、疑似的なBasic認証の環境を構築できます。FiddlerをBasic認証サーバーとして環境構築する手順をまとめてみました。 設定方法 前提: * Fiddlerがインストール済みの前提となります。インストール手順は色々なところで掲載されているので割愛します(以下が参考になると思います)。 * https://qiita.com/taketakekaho/items/397bc6e9afa32329edd0#特定のブラウザ通信やページのみにフィルタする * https://www.ipa.go.jp/files/000077215.pdf * Fiddler Classic を利用してます(最近はFiddlerのページからインストーラをダウンロードするとFiddler Everywhereが落ちてくるようです)。 手順: 1. まずBasic認証で使用するためのユーザークレデンシャル(ユーザー名とパスワード)を設定しま]]></description><link>https://jikoblog.netlify.app/fiddler-basic-authentication/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3e4</guid><category><![CDATA[Fiddler]]></category><category><![CDATA[Proxy]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Tue, 10 Nov 2020 20:06:02 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1Ct9gwQcvyL-bqG6zwSxlFyYP3v-juGTL" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1Ct9gwQcvyL-bqG6zwSxlFyYP3v-juGTL" alt="FiddlerでBasic認証のプロキシ環境を構築する"/><p>FiddlerはHTTP/HTTPS通信をキャプチャーするツールとして有名ですが、端末のプロキシサーバーとして使用することができ、疑似的なBasic認証の環境を構築できます。FiddlerをBasic認証サーバーとして環境構築する手順をまとめてみました。</p> <h1 id="設定方法">設定方法</h1> <p>前提:</p> <ul><li>Fiddlerがインストール済みの前提となります。インストール手順は色々なところで掲載されているので割愛します(以下が参考になると思います)。<ul><li><a rel="noopener" href="https://qiita.com/taketakekaho/items/397bc6e9afa32329edd0#特定のブラウザ通信やページのみにフィルタする" target="_blank">https://qiita.com/taketakekaho/items/397bc6e9afa32329edd0#特定のブラウザ通信やページのみにフィルタする</a></li><li><a rel="noopener" href="https://www.ipa.go.jp/files/000077215.pdf" target="_blank">https://www.ipa.go.jp/files/000077215.pdf</a></li></ul></li><li><a rel="noopener" href="https://www.telerik.com/download/fiddler" target="_blank">Fiddler Classic</a> を利用してます(最近は<a rel="noopener" href="https://www.telerik.com/fiddler" target="_blank">Fiddlerのページ</a>からインストーラをダウンロードするとFiddler Everywhereが落ちてくるようです)。</li></ul> <p>手順:</p> <ol> <li>まずBasic認証で使用するためのユーザークレデンシャル(ユーザー名とパスワード)を設定します。ユーザークレデンシャルはbase64エンコードする必要があるので、FiddlerのTextWizardを [Tools] -> </li> </ol>[TextWizard] から開きます。 <p><img src="https://docs.google.com/uc?id=1_zOoum9GpFrRdTh2pZHVyy-AlG-ucjIs" alt="FiddlerでBasic認証のプロキシ環境を構築する" loading="lazy"/></p> <ol start="2" style="--previous-count: 1"> <li>TextWizardの上段にユーザークレデンシャルを以下の書式で入力します。</li> </ol> <pre class="wp-block-code"><code><ユーザー名>:<パスワード></code></pre> <p>この例では以下で設定してます:</p> <ul><li>ユーザー名: testUser</li><li>パスワード: testPass</li></ul> <ol start="3" style="--previous-count: 2"> <li>base64エンコードされた文字列がTextWizardの下段に自動入力されるので、その文字列をコピーします。</li> </ol> <figure class="wp-block-image size-large is-resized"><img loading="lazy" src="https://docs.google.com/uc?id=1UlVdEob-BFT4MOnUx1szHHTuUS71LPJv" alt="FiddlerでBasic認証のプロキシ環境を構築する" class="wp-image-335" width="722" height="448"/></figure> <ol start="4" style="--previous-count: 3"> <li>Fiddlerの [QuickExec] に以下を入力し、エンターを押下します。</li> </ol> <pre class="wp-block-code"><code>prefs set fiddler.proxy.creds <手順3にてbase64エンコードした文字列></code></pre> <p>分かりずらいかもしれませんが、QuickExecは画面左下のこちらです。</p> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1Y-xdKoRjiupMWSiB9Q1eX4sm4gvf40ei" alt="FiddlerでBasic認証のプロキシ環境を構築する" class="wp-image-337"/></figure> <ol start="5" style="--previous-count: 4"> <li>[Rules] -> [Require Proxy Authentication] を選択し、プロキシ認証を有効化します。</li> </ol> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1wE7H6MLj9HF4JXY1VtPgqOsOuzzyKEGv" alt="FiddlerでBasic認証のプロキシ環境を構築する" class="wp-image-338"/></figure> <p>これで準備完了です!</p> <p>あとは、[File] -> [Capture Traffic] を選択して、通信キャプチャーを有効化した状態で、ブラウザからサイトにアクセスしてみましょう。ブラウザ上でプロキシ認証を通すよう促されます。</p> <figure class="wp-block-image size-large"><img src="https://docs.google.com/uc?id=1uRfIQZ16lszDb1c3pHr9-GqLtNIW7rje" alt="FiddlerでBasic認証のプロキシ環境を構築する" class="wp-image-336"/></figure> <p>手順2で設定したユーザークレデンシャルを入力すると、認証を通しページが見れるようになります!</p> <h1 id="使用用途">使用用途</h1> <p>で、ここまで設定手順を書いといてアレですが、いったい何に使うの?という話をします。正直、この機能の使用用途はものすごく限られていると思いますが、私はデスクトップアプリがプロキシのBasic認証に対応しているかの確認に使用しました。</p> <p>ブラウザに関しては特に気にする必要もないと思いますが、ことデスクトップアプリに関しては、ものによってはプロキシのBasic認証に対応しておらず、プロキシを通した通信が行えないという場合があります(以下は、とあるBasic認証に未対応なアプリで通信した際のアプリログ)。</p> <pre class="wp-block-code"><code>---> (内部例外 #0) System.Net.Http.HttpRequestException: この要求の送信中にエラーが発生しました。 ---> System.Net.WebException: リモート サーバーがエラーを返しました: (407) プロキシ認証が必要です 場所 System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context) 場所 System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) --- 内部例外スタック トレースの終わり ---<---</code></pre> <p>デスクトップアプリがBasic認証に対応しているか検証するうえで、手っ取り早く環境構築ができる機能になると思いました。</p> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Nexus 5X (LG-H791) で楽天アンリミットを試してみた]]></title><description><![CDATA[Nexus 5X で楽天アンリミットにつなげるか試してみました。結論から言うと、以下の結果のようにデータ通信は利用できるものの、音声通話/SMSが一部利用できませんでした。 楽天回線エリア (バンド3) パートナー回線エリア (バンド18/26) データ通信 〇 〇 音声通話/SMS 〇 ×[1] 考察 今回使用した Nexus 5X (LG-H791) の仕様は以下の通りです(こちらより一部抜粋): * CDMA: 非対応 * LTE(FDD): B1 / 2 / 3 / 4 / 5 / 7 / 8 / 9 / 17 / 18 / 19 / 20 / 26 / 28 * VoLTE非対応[2] 楽天回線エリアおよびパートナー回線エリア(au回線)の両方のバンドに端末が対応していることから、データ通信(4G LTE)は使用可能という結果になりました。 ※ちなみに、優先ネットワークの設定でLTE Onlyを選択[3]しなければ、4Gにつなぐことができませんでした。 隠しコマンド「*#*#4636#*#*」から開いた画面 ]]></description><link>https://jikoblog.netlify.app/rakuten-unlimit-nexus5/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3e2</guid><category><![CDATA[モバイル]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Sun, 13 Sep 2020 17:54:19 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1nNGrrQdKZjhsl3avp7mHCloBlfkcnx4_" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1nNGrrQdKZjhsl3avp7mHCloBlfkcnx4_" alt="Nexus 5X (LG-H791) で楽天アンリミットを試してみた"/><p>Nexus 5X で楽天アンリミットにつなげるか試してみました。結論から言うと、以下の結果のようにデータ通信は利用できるものの、音声通話/SMSが一部利用できませんでした。</p> <table> <thead> <tr> <th/> <th>楽天回線エリア<br>(バンド3)</br></th> <th>パートナー回線エリア<br>(バンド18/26)</br></th> </tr> </thead> <tbody> <tr> <td>データ通信</td> <td>〇</td> <td>〇</td> </tr> <tr> <td>音声通話/SMS</td> <td>〇</td> <td>×<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></td> </tr> </tbody> </table> <h2>考察</h2> <p>今回使用した Nexus 5X (LG-H791) の仕様は以下の通りです(<a rel="noopener" href="https://support.google.com/nexus/answer/6102470?hl=ja#nexus_5x" target="_blank">こちら</a>より一部抜粋):</p> <ul> <li>CDMA: 非対応</li> <li>LTE(FDD): B1 / 2 / <strong>3</strong> / 4 / 5 / 7 / 8 / 9 / 17 / <strong>18</strong> / 19 / 20 / <strong>26</strong> / 28</li> <li>VoLTE非対応<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></li> </ul> <p>楽天回線エリアおよびパートナー回線エリア(au回線)の両方のバンドに端末が対応していることから、データ通信(4G LTE)は使用可能という結果になりました。</p> <p>※ちなみに、優先ネットワークの設定でLTE Onlyを選択<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>しなければ、4Gにつなぐことができませんでした。</p> <p><img src="https://docs.google.com/uc?id=1U2tfhqLBwqA0KrSMBIAThkOQHUkI-uki" alt="Nexus 5X (LG-H791) で楽天アンリミットを試してみた" loading="lazy"><br> <em>隠しコマンド「*#*#4636#*#*」から開いた画面</em></br></img></p> <p>しかし、音声通話・SMSは回線によって結果が分かれました。端末がVoLTEに対応してないことが原因と推察します。VoLTEが使用できないことで、3Gフォールバックしても、au回線のCDMA 1X WINには端末が非対応でつなぐことができずに、電話回線が利用できないのかもしれません。</p><hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>Rakuten Link使用により発信のみ可能(データ通信が利用される) <a href="#fnref1" class="footnote-backref">↩︎</a></p> </li> <li id="fn2" class="footnote-item"><p>おそらくGoogle版の端末のため(<a href="https://www.itmedia.co.jp/mobile/articles/1510/08/news153_2.html">こちら</a>の記事によると大手プロバイダー経由で購入すると対応されている模様) <a href="#fnref2" class="footnote-backref">↩︎</a></p> </li> <li id="fn3" class="footnote-item"><p>電話アプリから「*#*#4636#*#*」と入力することで開けます(もしくは<a href="https://play.google.com/store/apps/details?id=com.shanehoban.phoneinfodialer">こちら</a>のようなアプリから開けます) <a href="#fnref3" class="footnote-backref">↩︎</a></p> </li> </ol> </section> <!--kg-card-end: markdown--></hr>]]></content:encoded></item><item><title><![CDATA[Xperia XZs 602SOで楽天アンリミットのパートナー回線が使用できない件]]></title><description><![CDATA[ それは、先日実家に帰省するために下り電車の東海道線に乗って横浜駅を通り過ぎたときのことでした。 あれれ?スマホが4Gにつながらない。。。 いやいや、きっと基地局間でハンドオーバーがうまくいってないだけだよー、って思いましたが、その後も一向に4Gにつながらない。。。 あとで調べてみたら、以下が分かりました。 どうやら、私が使っている端末 Xperia XZs 602SO (2017年にSoftbankより購入)がパートナー回線(au回線)のバンドを受け付けていなかったようです。 Xperia XZs 602SOの対応周波数(4G LTEのみ) 周波数帯バンドXperia XZs対応Note2.0GHzバンド1〇Softbank契約時はきっとこれ使ってた1.7GHzバンド3〇楽天回線エリア900MHzバンド8〇1.5GHzバンド11800MHzバンド18/26auプラチナバンド ※楽天パートナー回線エリアはこれ800MHzバンド191.5GHzバンド21700MHzバンド283.5GHzバンド42 つまり、楽天回線エ]]></description><link>https://jikoblog.netlify.app/rakuten-unlimit-xperia/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3e1</guid><category><![CDATA[モバイル]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Mon, 07 Sep 2020 21:23:05 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1nNGrrQdKZjhsl3avp7mHCloBlfkcnx4_" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: html--> <img src="https://docs.google.com/uc?id=1nNGrrQdKZjhsl3avp7mHCloBlfkcnx4_" alt="Xperia XZs 602SOで楽天アンリミットのパートナー回線が使用できない件"/><p>それは、先日実家に帰省するために下り電車の東海道線に乗って横浜駅を通り過ぎたときのことでした。</p> <p>あれれ?スマホが4Gにつながらない。。。</p> <p>いやいや、きっと基地局間でハンドオーバーがうまくいってないだけだよー、って思いましたが、その後も一向に4Gにつながらない。。。</p> <p>あとで調べてみたら、以下が分かりました。</p> <p>どうやら、私が使っている端末 Xperia XZs 602SO (2017年にSoftbankより購入)がパートナー回線(au回線)のバンドを受け付けていなかったようです。</p> <h1 id="Xperia XZs 602SOの対応周波数(4G LTEのみ)">Xperia XZs 602SOの対応周波数(4G LTEのみ)</h1> <figure class="wp-block-table alignfull"><table><thead><tr><th class="has-text-align-center" data-align="center">周波数帯</th><th class="has-text-align-center" data-align="center">バンド</th><th class="has-text-align-center" data-align="center">Xperia XZs対応</th><th>Note</th></tr></thead><tbody><tr><td class="has-text-align-center" data-align="center">2.0GHz</td><td class="has-text-align-center" data-align="center">バンド1</td><td class="has-text-align-center" data-align="center">〇</td><td>Softbank契約時はきっとこれ使ってた</td></tr><tr><td class="has-text-align-center" data-align="center">1.7GHz</td><td class="has-text-align-center" data-align="center">バンド3</td><td class="has-text-align-center" data-align="center">〇</td><td>楽天回線エリア</td></tr><tr><td class="has-text-align-center" data-align="center">900MHz</td><td class="has-text-align-center" data-align="center">バンド8</td><td class="has-text-align-center" data-align="center">〇</td><td/></tr><tr><td class="has-text-align-center" data-align="center">1.5GHz</td><td class="has-text-align-center" data-align="center">バンド11</td><td class="has-text-align-center" data-align="center"/><td/></tr><tr><td class="has-text-align-center" data-align="center">800MHz</td><td class="has-text-align-center" data-align="center">バンド18/26</td><td class="has-text-align-center" data-align="center"/><td>auプラチナバンド<br>※楽天パートナー回線エリアはこれ</br></td></tr><tr><td class="has-text-align-center" data-align="center">800MHz</td><td class="has-text-align-center" data-align="center">バンド19</td><td class="has-text-align-center" data-align="center"/><td/></tr><tr><td class="has-text-align-center" data-align="center">1.5GHz</td><td class="has-text-align-center" data-align="center">バンド21</td><td class="has-text-align-center" data-align="center"/><td/></tr><tr><td class="has-text-align-center" data-align="center">700MHz</td><td class="has-text-align-center" data-align="center">バンド28</td><td class="has-text-align-center" data-align="center"/><td/></tr><tr><td class="has-text-align-center" data-align="center">3.5GHz</td><td class="has-text-align-center" data-align="center">バンド42</td><td class="has-text-align-center" data-align="center"/><td/></tr></tbody></table><figcaption>出典: <a rel="noopener" href="https://cdn.softbank.jp/mobile/set/common/pdf/support/usim/unlock_procedure/frequency-band-list.pdf" target="_blank">https://cdn.softbank.jp/mobile/set/common/pdf/support/usim/unlock_procedure/frequency-band-list.pdf</a></figcaption></figure> <p>つまり、楽天回線エリア内ではXperia XZsでも4Gが入るものの、ひとたび楽天回線エリアから出てしまうと、パートナー回線エリアに切り替わり、端末が対応してないことでネットがつながらなくなってしまう、という状況だったようです。</p> <h1 id="楽天アンリミットのサービスエリア">楽天アンリミットのサービスエリア</h1> <p><a rel="noopener" href="https://network.mobile.rakuten.co.jp/area/?l-id=gnavi_area" target="_blank">こちら</a>のエリア図によると、JR東海道線で横浜駅から戸塚駅に向かう途中で、楽天回線エリアから外れ、パートナー回線エリアに切り替わってしまうようです(2020/09/07時点)。</p> <figure class="wp-block-image size-large is-style-default"><a href="https://docs.google.com/uc?id=15UXZcE2HmImq72S2LsseaFNQf_CqkX34"><img src="https://docs.google.com/uc?id=15UXZcE2HmImq72S2LsseaFNQf_CqkX34" alt="Xperia XZs 602SOで楽天アンリミットのパートナー回線が使用できない件" class="wp-image-297"/></a><figcaption>© Rakuten Mobile, Inc.</figcaption></figure> <p>5月末に楽天アンリミットを利用開始してから、3か月以上経って今更気付くという。。。住んでる地域が楽天回線エリアで使えちゃってた、かつ昨今の外出自粛で全然遠出してなかった、ことで良くも悪くも全く気付きませんでした。</p> <p>うーん、でも思い返せば、楽天回線エリア内でも建物の中などバンド3の電波が入りにくい場所では、確かにauローミングされずにただネットがつながらなかったよな。これのせいだったのか!</p> <p>てっきり端末のSIMロックを解除できれば、どんなSIM入れても使えるのだと思ってましたが、端末がプロバイダーのバンドを受信できるかということも確認しないとダメなんですね。以後、端末の購入やSIMの契約をするときには気を付けないといけないポイントだと思いました。</p> <!--kg-card-end: html--><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://network.mobile.rakuten.co.jp/fee/un-limit/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">2022年7月1日スタート予定!Rakuten UN-LIMIT VII(料金プラン) | 楽天モバイル</div><div class="kg-bookmark-description">シンプルなワンプラン「Rakuten UN-LIMIT VII(ラクテンアンリミットセブン)」が2022/ 7/1(金)スタート予定!どれだけ使っても月々2,980円(税込3,278円)使わない月はドンドン安くなる!6/1(水)より先行してスタートキャンペーン開始!他にも楽天市場のお買い物がおトクになったりスマホで楽しめる特典が盛りだくさん!楽天ポイントがザクザク貯まる!※アンリミテッドではありません</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://network.mobile.rakuten.co.jp/google-search-icon.png" alt="Xperia XZs 602SOで楽天アンリミットのパートナー回線が使用できない件"><span class="kg-bookmark-author">楽天モバイル</span><span class="kg-bookmark-publisher">楽天モバイル</span></img></div></div><div class="kg-bookmark-thumbnail"><img src="https://network.mobile.rakuten.co.jp/assets/img/common/ogp.png" alt="Xperia XZs 602SOで楽天アンリミットのパートナー回線が使用できない件"/></div></a></figure>]]></content:encoded></item><item><title><![CDATA[Boxのデバイストラストを使ってみた]]></title><description><![CDATA[Boxの「デバイストラスト」というログイン時に端末認証を行う機能を使用してみました。セットアップしたときに踏んだ手順を書き残しときます。 ログイン端末上に、ルート証明書によって署名されたクライアント証明書が存在しているか確認を行う「オプション1 – デバイス固有の証明書の検証」のセットアップ手順になります。 公式記事はこちら: https://support.box.com/hc/ja/articles/360044194993-デバイストラストのセキュリティ要件の設定 IT管理者側の事前準備 1. IT管理者がCA(「オレオレ認証局」でOK)にてルート証明書(後の手順で作成するクライアント証明書のルートとなる)を予め作成しておく openssl genrsa -out MyRootCA.key 2048 openssl req -x509 -new -nodes -key MyRootCA.key -sha256 -days 3650 -out MyRootCA.pem 2. Boxに管理者アカウントでログインし、管理コンソールに#1で作成した証明書(]]></description><link>https://jikoblog.netlify.app/configuring-box-device-trust/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3df</guid><category><![CDATA[Box]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Sat, 05 Sep 2020 14:32:31 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1kCe2dZKTcW-yK3fp5Hhp0aysJWkt3VwZ" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1kCe2dZKTcW-yK3fp5Hhp0aysJWkt3VwZ" alt="Boxのデバイストラストを使ってみた"/><p>Boxの「デバイストラスト」というログイン時に端末認証を行う機能を使用してみました。セットアップしたときに踏んだ手順を書き残しときます。</p> <p>ログイン端末上に、ルート証明書によって署名されたクライアント証明書が存在しているか確認を行う「オプション1 – デバイス固有の証明書の検証」のセットアップ手順になります。</p> <p>公式記事はこちら: <a href="https://support.box.com/hc/ja/articles/360044194993-%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%83%88%E3%83%A9%E3%82%B9%E3%83%88%E3%81%AE%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E8%A6%81%E4%BB%B6%E3%81%AE%E8%A8%AD%E5%AE%9A">https://support.box.com/hc/ja/articles/360044194993-デバイストラストのセキュリティ要件の設定</a></p> <h1 id="IT管理者側の事前準備">IT管理者側の事前準備</h1> <ol> <li>IT管理者がCA(「オレオレ認証局」でOK)にてルート証明書(後の手順で作成するクライアント証明書のルートとなる)を予め作成しておく</li> </ol> <pre><code class="language-bash">openssl genrsa -out MyRootCA.key 2048 openssl req -x509 -new -nodes -key MyRootCA.key -sha256 -days 3650 -out MyRootCA.pem </code></pre> <ol start="2" style="--previous-count: 1"> <li>Boxに管理者アカウントでログインし、管理コンソールに#1で作成した証明書(MyRootCA.pem)をアップロードする</li> </ol> <p><img src="https://docs.google.com/uc?id=1Bf5jrLtIaqGwEpJdPIC17dGAb-B8RmzZ" alt="Boxのデバイストラストを使ってみた" loading="lazy"/></p> <h1 id="クライアント証明書の発行">クライアント証明書の発行</h1> <ol> <li>クライアント側で秘密鍵(MyClient.key)とCSR(MyClient.csr)を発行して、CSRをCA(IT管理者)に提出する<br> ※クライアント側と書きましたが、作業自体はルート証明書発行した時と同じ環境で行ってもOK(CA上でクライアント証明書発行作業まで完結できます)</br></li> </ol> <pre><code class="language-bash">openssl genrsa -out MyClient.key 2048 openssl req -new -key MyClient.key -out MyClient.csr </code></pre> <ol start="2" style="--previous-count: 1"> <li>IT管理者が提出されたCSR(MyClient.csr)をもとに、事前に作成しておいたCAの証明書(MyRootCA.pem)で署名してクライアント証明書(MyClient.pem)を発行する<br> ※クライアント証明書(MyClient.pem)がユーザー配布用です。間違って、ルート証明書(MyRootCA.pem)をユーザーに渡さないように!</br></li> </ol> <pre><code class="language-bash">openssl x509 -req -in MyClient.csr -CA MyRootCA.pem -CAkey MyRootCA.key -CAcreateserial -out MyClient.pem -days 3650 -sha256 </code></pre> <ol start="3" style="--previous-count: 2"> <li>クライアント証明書を秘密鍵で署名してPFXを作成し、クライアント端末にインストールする</li> </ol> <pre><code class="language-bash">openssl pkcs12 -inkey MyClient.key -in MyClient.pem -export -out MyClient.pfx </code></pre> <p>ちなみに、クライアント証明書(MyClient.pfx)のインストール先は、利用しているBox Toolsの種類によって異なるのでご注意を!</p> <p><img src="https://docs.google.com/uc?id=1YSreBcex3dkKI1R-UAEYxjvhEfU9d5wv" alt="Boxのデバイストラストを使ってみた" loading="lazy"/></p> <blockquote> <p>[会社の証明書の確認] が有効な場合、Box Toolsが実行されているのと同じユーザーコンテキストで使用可能な証明書ストアに証明書をインストールする必要があります。例えば、マシン全般のインストール環境でBox Toolsが実行されている場合、デバイストラストのチェックはSYSTEMユーザーのコンテキストで実行されます。証明書をユーザーの証明書ストアにのみインストールする場合、デバイストラストのチェックが失敗することがあります。デバイストラストを機能させるため、(他の場所に加えて) ローカルマシンのプロファイルに証明書をプッシュする必要があります。</p> </blockquote> <p>Ref: <a href="https://support.box.com/hc/ja/articles/360044194993-%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%83%88%E3%83%A9%E3%82%B9%E3%83%88%E3%81%AE%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E8%A6%81%E4%BB%B6%E3%81%AE%E8%A8%AD%E5%AE%9A">https://support.box.com/hc/ja/articles/360044194993-デバイストラストのセキュリティ要件の設定</a></p> <p>以上でセットアップは完了です。お疲れ様でした!あとはログインの検証をしてみましょうー</p> <h1 id="出力ファイルおさらい">出力ファイルおさらい</h1> <p>この手順で作成されるファイルのまとめです。実際に使用するのは以下の2点:</p> <ul> <li>ルート証明書(MyRootCA.pem)を管理コンソールにアップロード</li> <li>クライアント証明書(MyClient.pfx)を端末にインストール</li> </ul> <table> <thead> <tr> <th>Output file</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>MyRootCA.key</td> <td>CAの秘密鍵</td> </tr> <tr> <td>MyRootCA.pem</td> <td>ルート(つまり自己署名)証明書</td> </tr> <tr> <td>MyClient.key</td> <td>クライアントの秘密鍵</td> </tr> <tr> <td>MyClient.csr</td> <td>クライアントのCSR(これをルート証明書で署名する)</td> </tr> <tr> <td>MyClient.pem</td> <td>クライアント証明書(ルート証明書によって署名済み)</td> </tr> <tr> <td>MyClient.pfx</td> <td>秘密鍵とクライアント証明書を内包したPKCS#12形式のクライアント証明書ファイル</td> </tr> </tbody> </table> <h1 id="おまけ">おまけ</h1> <p>クライアント証明書がルート証明書に署名されているか確認したい場合、<code>openssl</code>のサブコマンド<a href="https://www.openssl.org/docs/man1.1.1/man1/verify.html"><code>verify</code></a>で検証できます。</p> <pre><code class="language-bash">openssl verify -CAfile ルート証明書 クライアント証明書 </code></pre> <h5 id="">成功例</h5> <pre><code class="language-bash">$ openssl verify -CAfile MyRootCA.pem MyClient.pem MyClient.pem: OK </code></pre> <h5 id="">失敗例</h5> <pre><code class="language-bash">$ openssl verify -CAfile MyRootCA.pem MyAnotherClient.pem MyAnotherClient.pem: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd error 18 at 0 depth lookup:self signed certificate OK </code></pre> <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[BIGINT(20) unsignedの桁数について]]></title><description><![CDATA[BIGINT(20) unsignedというMySQLのデータ型が何桁まで表現できるのか調べてみました。このデータをString型の変数に代入するときに何文字になるのか気になったのが発端です。 カッコ内の数値は表示幅 MySQLデータベースを触っていて、ふととあるデータ型について疑問に思ったので、調べてみた。まず、こちらのテーブルのidというキーのデータ型をご覧いただきたい。 db> desc wp_table; +-------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+---------------------+------+-----+---------+----------------+ | id | bigint(20) unsigned | NO | PRI | NULL | auto_incremen]]></description><link>https://jikoblog.netlify.app/mysql-bigint-unsigned/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3de</guid><category><![CDATA[SQL]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Wed, 02 Sep 2020 21:29:51 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1BL0xKZcT-bFyEDa5H73SD2Dz9OHgWKuf" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1BL0xKZcT-bFyEDa5H73SD2Dz9OHgWKuf" alt="BIGINT(20) unsignedの桁数について"/><p>BIGINT(20) unsignedというMySQLのデータ型が何桁まで表現できるのか調べてみました。このデータをString型の変数に代入するときに何文字になるのか気になったのが発端です。</p> <h1 id="カッコ内の数値は表示幅">カッコ内の数値は表示幅</h1> <p>MySQLデータベースを触っていて、ふととあるデータ型について疑問に思ったので、調べてみた。まず、こちらのテーブルのidというキーのデータ型をご覧いただきたい。</p> <pre><code class="language-sql">db> desc wp_table; +-------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+---------------------+------+-----+---------+----------------+ | id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | +-------+---------------------+------+-----+---------+----------------+ </code></pre> <p class="is-style-default">私の素朴な疑問としては、<code>BIGINT(20) unsigned</code>って結局何ケタになるの?<br><br><code>BIGINT</code>は2<sup>64</sup>(8バイト)通りの数値を表せる。十進数に置き換えると、</br></br></p> <ul><li><code>signed BIGINT</code>であれば-2<sup>63</sup>~2<sup>63</sup>-1、または -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807</li><li><code>unsigned BIGINT</code>であれば、0~2<sup>63</sup>-1、または 0 ~ 1,844,674,407,370,955,161</li></ul> <p>の範囲が表現可能ということになるが、ではカッコ内の「20」は一体何なの?<br><br>ってことで、調べたところ、公式ドキュメントに以下のような記載がありました!</br></br></p> <blockquote class="wp-block-quote"><p><em><code>M</code></em> は整数型の最大表示幅を示します。最大表示幅は 255 です。<a href="https://dev.mysql.com/doc/refman/5.6/ja/numeric-types.html">セクション11.2「数値型」</a>で説明しているように、表示幅はその型に含めることができる値の範囲とは関係ありません。浮動小数点型と固定小数点型の場合、<em><code>M</code></em> は格納可能な桁数の合計です。</p><cite><a href="https://dev.mysql.com/doc/refman/5.6/ja/numeric-type-overview.html">https://dev.mysql.com/doc/refman/5.6/ja/numeric-type-overview.html</a></cite></blockquote> <p>どうやら、このカッコ内の数値 <em><code>M</code></em>(私の例では20)は最大表示幅を示しており(使用可能な値の範囲とは関係ない)、<code>ZEROFILL</code>オプションを利用している際に、ゼロ埋めを何ケタまで行うかのケタ数を指定するものらしい。</p> <p>例えば、<code>INT(5)</code>のデータ型を持つテーブルに123という3ケタのデータがある場合、00123という感じに5ケタになるようにゼロ埋めしてくれる幅のサイズを示しているとのこと。</p> <p>また、この定義は<code>ZEROFILL</code>機能に対して使用される機能であり、値の上限を示すものではないとのこと。よって、<code>INT(5)</code>に123456のような6ケタの値も格納可能。</p> <p>ちなみに、こちらのStack Overflowの記事で分かりやすく説明してくれてる方がいらっしゃいました。<br><a href="https://stackoverflow.com/questions/3135804/types-in-mysql-bigint20-vs-int20#answer-3135854">https://stackoverflow.com/questions/3135804/types-in-mysql-bigint20-vs-int20#answer-3135854</a></br></p><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[ExcelでUnixtimeを日付に変換]]></title><description><![CDATA[ExcelでUnixtime(ユニックスタイム)を日付に変換する方法について紹介します。ウェブ検索で見つけた数式を何も考えずにそのまま使ったらうまくいかなかったので、方法だけでなく仕組みや注意点についても備忘録的に書き残しておこうと思います。 Unixtimeとは この記事を読んでいる方は、Unixtimeとは何かご存知の上でここにたどり着いたのだと思いますが、結構重要なポイントがあるので見てみましょう。 Unixtimeとは、一言でいうとこういうやつです。 1598253617 そう、Unixtimeとは1970-01-01 00:00:00 (GMT)から何秒経過したかを示しています。よって、その秒数から日付を算出する計算式を組めば我々人間が直感的に理解できる日付の表示に変換できます。 そして、重要なポイントが2つあります。 1. UnixtimeはGMTなので、日本時間が知りたい場合は時差を考慮する必要がある 2. Unixtimeは上の例のように10ケタとは限らずデータ型によっては13ケタや16ケタだったりする(ケタ数が増えるほど精度が良く、]]></description><link>https://jikoblog.netlify.app/converting-unixtime-on-excel/</link><guid isPermaLink="false">Ghost__Post__62991dd7e25194000155e3dd</guid><category><![CDATA[Excel]]></category><dc:creator><![CDATA[kojimaru]]></dc:creator><pubDate>Sun, 30 Aug 2020 19:28:27 GMT</pubDate><media:content url="https://docs.google.com/uc?id=1sQXcu_IEGN-UZ_mIyLqmBOfq4ZL4QfGX" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://docs.google.com/uc?id=1sQXcu_IEGN-UZ_mIyLqmBOfq4ZL4QfGX" alt="ExcelでUnixtimeを日付に変換"/><p>ExcelでUnixtime(ユニックスタイム)を日付に変換する方法について紹介します。ウェブ検索で見つけた数式を何も考えずにそのまま使ったらうまくいかなかったので、方法だけでなく仕組みや注意点についても備忘録的に書き残しておこうと思います。</p> <h1 id="Unixtimeとは">Unixtimeとは</h1> <p>この記事を読んでいる方は、Unixtimeとは何かご存知の上でここにたどり着いたのだと思いますが、結構重要なポイントがあるので見てみましょう。</p> <p>Unixtimeとは、一言でいうとこういうやつです。</p> <pre><code>1598253617 </code></pre> <p>そう、Unixtimeとは1970-01-01 00:00:00 (GMT)から何秒経過したかを示しています。よって、その秒数から日付を算出する計算式を組めば我々人間が直感的に理解できる日付の表示に変換できます。</p> <p>そして、重要なポイントが2つあります。</p> <ol> <li>UnixtimeはGMTなので、日本時間が知りたい場合は時差を考慮する必要がある</li> <li>Unixtimeは上の例のように10ケタとは限らずデータ型によっては13ケタや16ケタだったりする(ケタ数が増えるほど精度が良く、13ケタはミリ秒単位、16ケタはマイクロ秒単位となります)。</li> </ol> <p>ちなみに、ネットで私が見つけた記事の多くはUnixtimeが10桁を前提としているようで、私の場合はお恥ずかしい話、桁数の違いのせいで計算がくるってしまいよくわからない値が出てちょっとばかりはまってしまいました。。。ので、これを書いてます!</p> <h1 id="Excelで変換してみる">Excelで変換してみる</h1> <p>では、Excelを使って変換する手順についてみていきたいと思います。</p> <p>Excelでは、日付は1900年1月1日を1とするシリアル値によって管理されてます(1日ずつ連番で、1900年1月2日は2になります)。<br> また、前述の通りUnixtimeは1970-01-01 00:00:00 (GMT)から何秒経過したかを示してます。</br></p> <p>以上より、Unixtimeを1日あたりの秒数(24*60*60)で割ることで1970年1月1日から経過した時間を秒単位ではなく日単位で取得し、1970年1月1日のシリアル値(25569)に足すことでExcel上で日付として使用できる値を取得できます。</p> <p>これを数式にしたのがこちらになります</p> <pre><code class="language-xlsx">= A1/(24*60*60) + DATE(1970,1,1) </code></pre> <ul> <li>A1のセルにunixtimeが入力されている想定</li> <li>DATE(1970,1,1)はシリアル値「25569」を返す</li> </ul> <p><img src="https://docs.google.com/uc?id=1oZNAEeBdV-oeMaJhAgDpvtamwv61ChW8" alt="ExcelでUnixtimeを日付に変換" title="Excelでunixtimeをシリアル値に変換" loading="lazy"/></p> <p>上記は、Unixtimeが10桁であることを想定した式になります。Unixtimeが13桁の場合はミリ秒単位の数値になるため、Unixtimeを1日あたりのミリ秒数(1000*24*60*60)で割ることで、ミリ秒単位を日単位に変換し、1970年1月1日にその日数を足すことで変換できます。16桁の場合も同じ原理で計算できます。</p> <h5 id="13">13桁の場合</h5> <pre><code class="language-xlsx">= A1/(1000*24*60*60) + DATE(1970,1,1) </code></pre> <h5 id="16">16桁の場合</h5> <pre><code class="language-xlsx">= A1/(1000*1000*24*60*60) + DATE(1970,1,1) </code></pre> <p>ちなみに、上記で出した日付はいずれもGMTなので、日本時間を取得するには時差(GMT+9)を考慮する必要があります。</p> <h5 id="gmt900">日本時間(GMT+9:00)に変換</h5> <pre><code class="language-xlsx">= A1/(24*60*60) + DATE(1970,1,1) + TIME(9,0,0) </code></pre> <h1 id="セルの表示形式を変更する">セルの表示形式を変更する</h1> <p>上の手順の数式を入力後、B1のセルには変換後のシリアル値が返されます。セルの表示形式をデフォルトのままにしていると、以下のように日付ではなくシリアル値で表示されてしまいます。</p> <p><img src="https://docs.google.com/uc?id=1g7LC5tDERCuJ2sPNlVq6xuLCkOAB3KT7" alt="ExcelでUnixtimeを日付に変換" loading="lazy"/></p> <p>その場合は、セルを選択し、右クリック > [セルの書式設定] を選択し、以下のダイアログでセルの書式を日付へと変更することで表示を切り替えられます。</p> <p><img src="https://docs.google.com/uc?id=1GN-7mEA5q3QKQ9Dz56iam0XwemBk6PVs" alt="ExcelでUnixtimeを日付に変換" loading="lazy"/></p> <p>私は上のスクショのように、[ユーザー定義]で以下を指定して、秒数まで表示する書式をよく使います。</p> <pre><code>yyyy/mm/dd h:mm:ss </code></pre> <!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>