僕は発展途上技術者

Rails 3 での CSRF 対策 - エラー時に ActionController::InvalidAuthenticityToken error は表示されない

Rails 3.2.3 での CSRF 対策について調べていて、ちょっとはまったポイントがあったのでメモを残しておきます。

Rails はデフォルトで特に何もしなくても POST/PUT/DELETE のリクエストに対して authenticity_token という hidden のパラメーターを利用して CSRF 対策をおこなってくれる仕組みを持っている。(Ruby On Rails ピチカート街道 - Rails 2.0・その12(CSRFを勝手に防止) - などが参考になる)

しかしそれは Rails の form_for などのヘルパーを使った場合で、form タグを自分で書いた場合には、


<%= hidden_field_tag :authenticity_token, form_authenticity_token %>


のように手動で authenticity_token パラメーターを作って POST のパラメーターとして送る必要がある。

authenticity_token を送らない場合の挙動を確認したくて、適当に scaffold で model/view/controller 一式を作成し、form_for ヘルパーを使っている部分を以下のようにベタな html に書きなおし、あえて authenticity_token を送らないようにする。


<form accept-charset="UTF-8" action="/people" class="new_person" id="new_person" method="post">
<div class="field">
<label for="person_name">Name <input id="person_name" name="person[name]" size="30" type="text" />
</div>
<div class="actions">
<input name="commit" type="submit" value="Create Person" />
</div>
</form>


これで、POST のリクエストをおこなってもエラーとなって、新しいデータは作成されないと思ったのだが、予想に反してデータは作成されてしまう。

あれ、これだと CSRF 対策にならないじゃないか、と思いいろいろと試行錯誤。

ログをみると authenticity_token を送らない場合は

WARNING: Can't verify CSRF token authenticity

という WARNING のメッセージは確かに出ている。でも POST のリクエストは通ってしまう。

Rails 2.x を触っていたころの記憶では、authenticity_token を送ってない場合にエラーで悩まされた覚えがある。

で、しばしはまった後にわかったのは、authenticity_token を送らない場合は、POST のリクエストは通るのだが session がリセットされているということだった。

devise などで何らかのユーザー認証の仕組みをいれている場合に、POST/PUT/DELETE のアクションに対して、session に格納されているユーザー情報の値でもって認証をかけるのが普通だ。

これを scaffold でつくった簡単なフォームで擬似的に実現しようとすると、


class ApplicationController < ActionController::Base
protect_from_forgery

def authorize
unless session[:login]
redirect_to root_url, :notice => "not authorized"
end
end
end


のように session を確認する authorize メソッドを定義しておいて、PeopleController では、


before_filter :authorize, :only => [:create, :update, :destroy]


のように作成、変更、削除のアクションに対して authorize メソッドを before_filter でかける。

authenticity_token パラメーターを送らなかったり、値が違っている場合は session がリセットされるので、リクエスト自体は通っても authorize で蹴られてデータは作成されない。

「うーん、でもおかしいなあ、以前は確かにエラーではじかれた覚えがあるんだよなあ」と思って、もうちょっと調べていたら、Ruby on Rails Guides: Ruby On Rails Security Guide


If the security token doesn’t match what was expected, the session will be reset. Note: In Rails versions prior to 3.0.4, this raised an ActionController::InvalidAuthenticityToken error.



security token が期待された値とマッチしない場合はセッションがリセットされる。Rails 3.0.4 以前は ActionController::InvalidAuthenticityToken error を出していた。


とちゃんと書いてありました。

ドキュメントをきちんと読んでなかった僕が悪い。

Mac OS X 10.8 Mountain Lion に Ruby on Rails 環境をセットアップする

開発環境をセットアップするのが面倒なので、OS をアップグレードするたび Time Capsule からイメージをまるごとコピーしてきて、秘伝のタレのように使っています。そのため、一から環境構築というのはめったにやらないのですが、今回、いつも使っている MacBook Air とは別に自宅用に Mac mini を買ったので、久々に Ruby on Rails の環境をセットアップしました。せっかくなので、まっさらの Mac OS X 10.8 Mountain Lion に Ruby on Rails をセットアップする手順例としてその手順を記録しておきます。

最近の Rails の環境構築は、gcc 入れた後に Ruby やら RVM やら Git やらを入れなくてはいけなくて、相当面倒です。しかし、RailsInstaller はそれらを一気にインストールしてくれます。

リンク先の DOWNLOAD the KIT をクリックしてインストールファイル(RailsInstaller-1.0.3-osx-10.7.app.tgz)をダウンロードします。

ダウンロードしたファイルをダブルクリックして展開します。

展開したファイルをダブルクリックすればインストールが開始されます...

のはずなのですが、ここで「"RailsInstaller-1.0.3-osx-10.7"は、開発元が未確認のため開けません。」というエラーが出てしまいます。

Mountain Lion からなのでしょうか?デフォルトの設定では、Mac App Store と確認済みの開発元からのアプリケーションでないとアプリケーションの実行が許可されていないので、

[システム環境設定] > [セキュリティとプライバシー]

を選んだあと、左下の鍵マークを外し、[一般] タブの [ダウンロードしたアプリケーションの実行許可:] で、[すべてのアプリケーションを許可] を選びます。

このあと、もう一度先ほど展開したファイルをダブルクリックすればインストールが開始されます。

必要な方は、この後 [セキュリティとプライバシー] の設定を元の、[Mac App Store と確認済みの開発元からのアプリケーションを許可] に戻しておきます。

RailsInstaller のインストールについては、指示通り進んでいけば特に問題はないと思います。

インストール後、


$ ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.4.0]
$ rails -v
Rails 3.2.8


のように ruby や rails の最新版がインストールされていれば成功です。

iPhone プログラミングを CoderDojo Tokyo で教え始めました

CoderDojo Tokyo は毎週日曜日下北沢オープンソースカフェでおこわれている小中学生にプログラミングを教える活動です。

小学生にはおもに教育用プログラミング言語のスクラッチ、中学生には HTML や Javascript を教えていましたが、最近は iOS アプリを作りたいというこどももでてきているので、実験的な試みで、iPhone アプリ開発を教えられるメンターを育てるメンター養成道場をおこないました。

実は、CoderDojo をきっかけにして、わが息子に教えたかったというのが本音のところで、本当にこどもでも iPhone アプリ開発ができるのかモニターの意味も含めて、長男も混ぜてもらいました。

「15歳からはじめる iPhone わくわくゲームプログラミング教室」をテキストにして、第一回目の本日は一時間で開発環境のセットアップ、xCode の使い方をざっと習い、iPhone シミュレーターにダイアログを表示して Hello World など好きなテキストを表示するまでをやってみましたが、なかなかの好感触でした。



結論としては、小学生上級生で、スクラッチなどでプログラミングの基本がわかっていればできそうという感じ。ほかのメンターの方たちもこのテキスト通りすすめるのであれば、教えられそうということでした。

それもこれも、テキストが非常に良く書かれていることに負うところが大きく、たとえば


  • 最初にわかりやすく iPhone でゲームプログラミングをすることの概念的な説明(コンパイルとはどういうことかや、iPhone では使えるメモリ容量が制限されていることなど)が書かれている。

  • 半角/全角文字を間違える、小文字と大文字を間違える、セミコロンとコロンを間違えるなど、あらかじめはまりそうなポイントを先回りして注意を惹起している。

  • viewDidAppear といったメソッド名を view は「画面」、did は「した」、Appear は 「現れる」というように英語をくっつけたものですよ、というように丁寧に解説している。



といった点は、著者が実際にこのテキストの通りにこどもたちに教えている経験に基づいていることを感じさせます。

こどもに iPhone アプリを教えたいというかたに限らず、プログラミングは初めての大人でも今から iPhone アプリを開発してみたいという人にもおすすめの一冊ではないだろうか。

以下、養成道場をすすめ、これから CoderDojo で実際に iPhone アプリ開発を教えるとしたらを念頭にいれて、いくつか気づいたことやポイントを。


  • 最初の Xcode のダウンロードやインストールなど、開発環境のセットアップは面倒かつ時間を食うので、できたら事前に済ませてもらうのがよい。

  • iPhone シミュレーターで動かす分には、無料で済むが、作ったアプリを実機で動かすには、年間参加費 ¥8,400 の開発者登録が必要。シミュレーターだけで動かすなんて、きっとこどもは満足するわけはないので、この出費がかかることを必ず親に理解してもらう必要がある。

  • 小学生は ( と ) の括弧しかしらない。Objective C には { と } の中括弧、[ と ] の大括弧も駆使する必要があるので、最初によく説明しておく。

  • [追記] 特に英語の英才教育などやっていないため、英語がさっぱりわかりません。アルファベットは一応学校でやったのでわかっているようですが、大文字小文字の区別がおぼつかない。

  • スクラッチはブロックを組み合わせるだけでよかったところが、Objective C ではすべて全部書かないといけないところで、はやくもうちの息子は萎えていた。けれども、Xcode の補完の機能を使いこなすコツをよく教えたら、なんかロボットに助けてもらっているような感覚で気持ちがいいと言っていた。

  • テキストではプロジェクト作成のところで ARC(Automatic Reference Counting) を無効にしている。この通りに従わないと、release 文のところでエラーがでるので、この間違いに気づいたら早めにプロジェクトを作り直す。

  • 大人のメンターから型宣言のところの * は何ですか、という質問が。。ポインタうんぬんの説明は難しそうなので、後回し。それとなくスルー :-) まずは動かしみて「動いた!」という感動を体験させてあげるのが重要。

  • ダイアログを表示できただけでもうれしかったようで、帰ってから妻や弟にみせていた。まあ、見せられたほうは「え、こんだけ」という本心を隠すのに苦労していたようだが。。

  • 最初のセットアップや Xcode の使い方で、慣れている人がガイドしてあげるのは大変重要だと思った。大人でも独学でやればおそらく4、5倍の時間を食ってしまうんじゃないかと思うほどはまりポイントが満載。

  • こどもがスクラッチをやっていてプログラミングの基礎はわかっているのは大きい。変数に代入とかメソッドに命令を渡すというところは、スクラッチに置き換えて説明すればすんなりわかってくれる。

  • 自分のこどもを他人と混ぜて教えるのは、家だとなかなかやらないところを教え始めるきっかけになったというのと、肉親同士だと険悪になるところを他人の目もあるのでやさしく丁寧に教えてあげることができる、という2つのメリットがあって、これは使えるライフハック!






↑ iPhoneで始めてのHello world!

今後も不定期ながら、iOS アプリ教室は続けていくので、もし興味がありましたら、Twitter で @jishiha をフォローしてくれるなり、CoderDojo Tokyo のページからたどれる Facebook のグループページなどで情報をウォッチしてみてください。

スクールプレゼンター(通称スクプレ)の教材データを共有するサイト、「スクプレ道場」を制作しました

[スクールプレゼンター](http://www.culture-pro.co.jp/SchoolPresenter/)(通称スクプレ)という小学校の先生向けに開発された教材作成ツールがあるのですが、そのツールで作成した教材データを共有できるサイト「スクプレ道場」を制作させていただきました。

» スクールプレゼンター教材共有サイト - スクプレ道場

スクールプレゼンター教材共有サイト - スクプレ道場


Facebook アカウントでログインすれば、実質スクプレを使っている先生に限られますが誰でも教材を投稿できます。閲覧しダウンロードするにはアカウントは不要なので、こちらは本当に誰でも利用できるようになっています。Ruby on Rails で開発し Heroku にホスティング、Twitter Bootstrap を使ってスマホでも閲覧できるようにレスポンシブデザインにしました。

教育関係のサイトやサービスというのは、失礼を承知で書くと、十年前から時が止まってしまったようなものが多い印象がある中で、敢えて自分が今ウェブサービスをつくるとしたらこう作るという手法ばかりを使って「スクプレ道場」を作ってみました。

そもそも何で学校の先生でもないのに、このようなサイトを作ることになったか?と思われるかもしれません。その経緯について以下に紹介したいと思います。

知育ゲームアプリ[かなぶん](http://ja.kanabun.org/)を出したばかりの頃、小学校の教員をやっている妹から「こういうものがあるけれど興味がある?」ということで紹介してもらったのがそもそものきっかけとなった[算数授業ICT研究会](http://www.sansu-ict.jp/)でした。算数の授業にICTをどう取り入れるかを考える研究会で、参加してみたらまわりは学校の先生ばかりという完全アウェイの状況でしたが、算数の模擬授業などを見て単純に見るもの全てが新鮮でとても楽しめました。

その模擬授業で使われていたのがスクールプレゼンターで、次に実際に教材を作ってみる実習に参加して体験させてもらったあとに、妹に「ああいうの使ってみたりするの?」と聞いてみたところ、あっさり「私には無理」という答え。僕と同じ血が流れているとは想像できないくらい IT 音痴な妹にとっては、すでにできている教材データを使って操作するくらいならできるけれど、教材データを自分で作るというのは全然考えられないとのことでした。ならば誰か得意な人が教材データを作ってネット上で共有すればいいじゃないかというのがプログラマー脳な僕の発想です。

研究会の後の懇親会にまでのこのこ着いていった僕は、妹との上記の会話もあって、「学校の授業の進め方やたとえばスクプレの教材データなんか、もっと学校を越えて先生の間でどんどん共有すればいいのに」といった話を先生方にしました。教育関係の本なども書き、妹にとっては有名人なえらい先生もいらっしゃったようなのですが、門外漢な僕はまったく遠慮を知りません。調子にのって、「コンピューターのソフトウェアの世界ではオープンソースという考え方があって。。」などと説明していたら、当のスクールプレゼンターを開発している[株式会社カルチャー・プロ](http://www.culture-pro.co.jp/homepage/index.html)の担当の方、伊藤剛さんをその場で紹介していただいたのです。

改めて、伊藤さんにスクプレで作成した教材データを共有できるウェブサイトがあったらいい、という話をしたところ、それは面白いぜひやりましょうということになり、販売元の内田洋行など関係者の方々に提案、説得してまわってくださり「スクプレ道場」を開発させていただける運びとなったのです。

開発する最初の段階ではまだ Facebook が広く知られていなかったため、Facebook アカウントでログインできるようにしたらどうか?とか各教材データに対して「いいね」できるようにして「いいね」順に並べたらどうか?などの提案の数々に対して、正直、こいつは何を言っているんだろう?と思われたのかもしれないのですが、ひとつひとつ丁寧に説明していくことで理解していただけたのだと思います。

まだリリースしたばかりなので、まだまだこれからなのですが、こうした試みがうまくいったと言ってもらえるようできるだけの協力をしていきたいと思っています。

学校の先生の方、良かったら使ってみて下さい。まわりにそういう人がいるという方、もし良かったら紹介してあげてみてください。

» スクールプレゼンター教材共有サイト - スクプレ道場



↑こんな感じで自分のブログに教材ファイルの案内を貼り付けることもできます

iOS の UIWebView で UserAgent を変える簡単な方法とその落とし穴

iOS の UIWebView で UserAgent を変えるのって意外とややこしいという認識だったのですが、検索して調べてみたら簡単な方法がありました。

» [Easily set the User-Agent in a UIWebView \| MPHWeb](http://www.mphweb.com/en/blog/easily-set-user-agent-uiwebview)

で紹介されている方法で以下のたった三行で済みます。



これで十分だったのですが、思わぬ落とし穴が。。

UserAgent を変更したアプリに AdMob のバナーを貼っていたのですが、広告がまったく表示されなくなってしまいました。

上記方法だと、すべてのリクエストの UserAgent を変えてしまうことになり、どうも変更前の通常の UserAgent を送っていないと AdMob 側でバナーを表示しないようになっていたようです。

AdMob を使っている方はご注意を。。

というわけで、僕は上記方法を断念しましたが、UserAgent を単に変更したいだけならば使えると思います。

Chrome で、Google 日本語版と英語版を素早く検索する方法、およびその他の便利な検索ワザ

前回の

» プログラマーがてっとり早く検索スキルを上げる方法

で Google 日本語版と Google 英語版とをうまく使い分けることを説明しましたが、その具体的な方法を紹介します。

紹介する方法は Chrome での方法です。他のブラウザでも似たようなことはできると思います。

Chrome には、あらかじめキーワードを登録して、アドレスバーにそのキーワードと文字列をつなげて打ち込むと素早く検索できる機能があります。たとえば、「ruby」を検索したいなと思ったら、アドレスバーに「g ruby」と入力するだけです。

これを実現するにはあらかじめ g というキーワードを登録しておきます。Chrome のメニューから「環境設定」を選択、なかほどの「検索エンジンの管理...」というボタンを押します。

「検索エンジン」というウィンドウが開くので、一番下にいって、名前、キーワード、URL の順に登録します。




僕の Chrome には g と gj が以下のように登録されていて、Google 英語版で検索したいときは「g rails」と打ち込み、Google 日本語版で検索したいときは「gj ruby」と入力します。



登録している URL は以下の通り、%s のところがキーワードで置き換えらます。


g:
http://www.google.com/search?hl=en&source=hp&q=%s&btnG=Google+Search&aq=f&aqi=&aql=&oq=&gs_rfai=



gj:
http://www.google.co.jp/search?hl=ja&source=hp&q=%s&btnG=Google+Search&aq=f&aqi=&aql=&oq=&gs_rfai=


他にもいくつかキーワードを登録していて便利なのでいくつか紹介しておきます。

英辞郎



「e ruby」で「ruby」を ALC の英辞郎 on the WEB で検索します。


e:
http://eow.alc.co.jp/%s/utf-8/


Amazon



「a 1Q84」で Amazon を検索します。


a:
http://www.amazon.co.jp/gp/search?field-keywords=%s&index=blended&__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A


Google マップ



「m 東京駅」で Google マップを検索します。


m:
http://maps.google.co.jp/maps?oi=map&q=%s


YouTube



「y 浜田省吾」で YouTube を検索します。


y:
http://www.youtube.com/results?search_query=%s&page={startPage?}&utm_source=opensearch


自分のツイートを検索



自分のツイートを検索したいときは「t rails」で twilog を検索します。jishiha のところは twitter のアカウント名なので、自分のものに置き換えて下さい。


t:
http://twilog.org/tweets.cgi?id=jishiha&word=%s


以上は、一般的なもの。

これ以降はプログラマー特有のものを紹介します。

stackoverflow



最近は Google で検索するより Stack Overflow を直接検索した方が早いというときがあります。そんなときは「s rails」で SO を検索します。


s:
http://stackoverflow.com/search?q=%s


iOS Reference Library



iOS アプリを開発しているときは、Apple のドキュメントを検索したいときがあります。そんなときは「i uiwebview」で検索します。site:developer.apple.com をキーワードに追加して Google 検索しています。


i:
http://www.google.com/search?hl=en&source=hp&q=%s+site%3adeveloper.apple.com&btnG=Google+Search&aq=f&aqi=&aql=&oq=&gs_rfai=


Android Developers Reference



Android アプリを開発しているときは、「d webview」です。a は Amazon とかぶるので、キーワードは Droid の d にしています。


d:
http://www.google.com/search?hl=en&source=hp&q=%s+site%3adeveloper.android.com&btnG=Google+Search&aq=f&aqi=&aql=&oq=&gs_rfai=


自分のブログを検索



site: キーワードを追加して Google 検索という技はいろいろと使えます。自分のブログだけを検索したいときもあって、そういうときは「h rails」です。h は「発展途上技術者」の h です。


h:
http://www.google.co.jp/search?hl=ja&q=%s+site%3ablog.champierre.com&btng=%e6%a4%9c%e7%b4%a2&lr=&aq=f&oq=


いろいろと自分がよく使う検索を登録して、便利に使ってみて下さい。

プログラマーがてっとり早く検索スキルを上げる方法

タイトルでは「プログラマーが。。」としているけれど、海外の情報を積極的に活用する立場にある人すべてに言えることだと思う。

プログラマーのスキルのひとつとして、検索して解決方法をみつける、というのはいまや超重要。その検索スキルを簡単に手早くレベルアップさせるのが、「英語のキーワードで検索すること」だと思っている。

技術情報のほとんどが英語で発信されており、日本語の情報はそれをなぞっただけのものであったり、単なる翻訳に過ぎないことが多い。日本語で検索してヒットした情報だけでは不十分で、結局英語で検索し直してより広範囲かつ詳細な情報を探すことが多い。日本語でみつけた情報の原文がヒットし、読んでみたら、翻訳が全然間違っていたなんてケースもある。

そうなってくると、技術的な情報が欲しいときには、検索結果には英語の情報だけが表示されて欲しくて、日本語の情報は邪魔なので表示されて欲しくない。「英語のキーワードで検索すること」というのは、「Google 日本語版で英語のキーワードで検索する」ことではなくて、「Google 英語版で英語のキーワードで検索する」ことなのです。

もちろん日本語の情報が欲しい時、たとえば「近くでおいしいところはないかなあ」なんていうときは Google 日本語版で検索するのは当たり前だ。技術情報でも日本語特有の問題(たとえば文字化け)を調べるときも Google 日本語版で検索する。

Google 英語版と Google 日本語版を切り替えて使いこなす必要があるのだけれど、これが意外と簡単にできなかったりする。普段 Google 日本語版を使っていれば、http://google.co.jp でなく http://google.com にアクセスしても Google 日本語版に飛ばされてしまう。

僕は Chrome のアドレスバーにキーワードを登録する方法で、この切り替えを実現していてそれについては次のエントリー

» Chrome で、Google 日本語版と英語版を素早く検索する方法、およびその他の便利な検索ワザ

で紹介しています。Chrome 以外のブラウザを使っている場合は、同じようなことを実現する方法があるはずなので調べていただきたい。

ここで言いたかったのは、技術情報を検索するときは「Google 英語版で英語のキーワードで検索する」ということでした。

Lokka で translation missing が出まくって困ってしまった場合の対処方法

しばらく前に、まったく何の変更も加えていないにもかかわらず、以下のキャプチャのようにこのブログを動かしている Lokka で translation missing が出まくってしまい、ブログを更新する気が全くうせてしまっていました。


おそらく Lokka が動いている Heroku で何らかの変更がおこなわれたことの影響だと思うのですが、やっと対処方法をみつけたので、もしかして同じ問題で困っている人もいるかもしれないと思って、以下に公開しておきます。

修正する必要があるのは lib/lokka/app.rb の38行目あたり、以下のように I18n.reload! の一行を追加します。



I18n.load_path にロケールファイルのパスを追加しても、ファイルが読み込まれていなかったようなので明示的に reload をしてみたのですが、このブログのほかにも Lokka で運用しているサイトではこのような問題は起こっていなかったので、なんでそうなってしまっているのか謎です。

RubyMotion で API にアクセスし、取得した JSON をパースして表示するサンプル

Ruby で iOS アプリを開発できる Ruby Motion を使ってアプリを作り始めているのですが、Objective C で開発していたときと比べて楽過ぎてヤバいです。

Ruby Motion だけでも充分楽になるのですが、さらに BubbleWrap というラッパーと一緒に使うと、コードがとってもシンプルになって楽しい。

どんなにコードがシンプルになるかをデモするために、API にアクセスし、取得した JSON をパースする、という良くあるパターンを含んだサンプルアプリを作ってみました。 

World Countries API にアクセスし、取得した JSON から国名のリストを作成し、画面をタップするごとにランダムに国名を表示します。

このサンプルを動かすには、

gem install bubble-wrap

で BubbleWrap をインストールしたあと、Rakefile に

require 'bubble-wrap'

を追加する必要があります。

アプリのソースコードは GitHub に置きました。


» champierre/RubyMotionSamples/Countries



RubyMotion で画像を View の上に表示する

備忘録的にメモ。





image = UIImage.imageNamed("icon.png")
@image_view = UIImageView.alloc.initWithImage(image)
@image_view.frame = CGRectMake(0, 0, 36, 36)
view.addSubview(@image_view)




view raw
gistfile1.txt
This Gist brought to you by GitHub.




表示したい画像の画像ファイルは resources 以下に置きます。

プロフィール

株式会社まちクエスト代表、つくる社LLC代表。

Scratchで楽しく学ぶ アート&サイエンスRaspberry Piではじめる どきどきプログラミングを書きました。

オンラインコンテンツ: 大人のためのScratch

Amazonから図書館検索 Libron、iPhoneアプリ ひらがなゲーム かなぶん を作っています。

Email: webmaster at champierre dot com

Twitter @jishiha

最近のエントリー

アーカイブ