Docker+Rails+webpacker ~facebook api を叩くためのssl設定~
twitter apiに引き続き今度はfacebookのgraph apiを叩きます. (まだ取得まで出来てませんがここまでをメモしておきます).
※因みに twitter apiをrails側からではなくブラウザ側(Reactでfetch)したらcorsでエラー吐かれました. どうやらtwitter apiはcorsに対応していないよう...
↑ 古い記事ですが....
なので素直にrails側からデータ取得してReact側に流すことにしました.
Facebook API のためのssl設定
facebook developers のサイトによると, graph api 利用にはhttps(ssl通信)が必要だそう.
herokuにあげたら恐らく勝手にhttpsにしてくれるんだけど, localhostでやる分にはrailsはデフォルトでhttp通信になってます. なので auth/facebookにアクセスしても, アクセス元がhttpsでない?ためエラー吐かれてoauth認証出来ません.
そこで下の記事を参考にssl化します.
force_sslの設定
Railsの app/config/environments/development.rb ファイルに,
を記述します. こうすることで, 全てのアクセスをhttpsにしてくれるらしい.
webpacker.ymlのssl設定
webpackはデフォルトでwebpack-dev-serverがhttp通信するそうなので, それもhttpsに変えます.
https://webpack.js.org/configuration/dev-server/#devserver-https
webpackの仕様
webpackerでは app/config/webpacker.yml でこの設定が出来ます. 以下のように書き換えます.
opensslで仮の証明書を作成
https通信を行う上ではsslサーバ証明書というものが必要になるので, それを作成します. 本来は認証局が発行するものらしいので, ここではあくまで動かすための仮のものということで.
恐らくコンテナ入らなくても docker-compose run --rm web openssl .... でいける ?
Procfileの書き直し
以上が終わったら, Procfileを書き直します.
rails側で動くサーバに先ほど作成したserver.key と server.crt を埋め込みます. するとhttpsで通信できるようになります. ただし
1. 初回アクセス時は 127.0.0.1:3000 ではアクセスできない問題
=> 今まではこれで大丈夫でしたが, 今度からは https://127.0.0.1:3000 と明示しないとうまくいかない....
2. 初回アクセス時は信頼されてないと警告が出る
=> 信用するとすればアクセスできます.
Graph API を開発者モードで動かす
facebookのapiであるgraph api ではユーザに求める情報(許可範囲)が適切であるか、アプリ公開前にfacebookに認証してもらわないといけないみたいです. なのでそのままでは取得できる情報が限られます.
現在のアプリがユーザから取得可能な情報は
/me?fields=permissions でわかる.
なので開発時にはテストユーザと呼ばれるアプリを許可した架空のユーザを作成します. そのユーザからはfacebookの認証なしに任意に設定した情報を取得可能です.
やり方は,
1. 自分の作成したアプリを選択
2. 役割 → テストユーザ → 追加 を選択
3. このアプリのテストユーザを許可「はい」→ 取得したい情報を選択
(ex.) user_post(ユーザの投稿情報), user_photos(投稿写真)
4. 編集 → パスワード変更
以上でこのアカウントでrailsアプリから auth/facebook にアクセスすると無事oauth認証画面に行きます.
因みに, .envファイルにfacebookのパスワードの記入も忘れずに.
これから
railsサイドからjavascriptのfetchみたいなのがうまくできなくてapi叩けてないので早く叩く.
あと悲報なのですが, instagramのapiはビジネスなんとかの審査通さないと利用できないみたいです........... 辛い
Rails+React with webpacker ~Herokuにデプロイ~
ここまでで簡単ですが
- twitter認証 + タイムライン表示
- postgresqlでデータベース構築
- devise認証
- Rails と React 間でaxiosで通信
できたので, いったんHerokuにデプロイできるかやってみました. ので, そのメモです.
dotenv-railsの導入
herokuにデプロイするにあたり, config/secrets.yml もアップロードしないといけません. ですが, 今までここにTwitterのAPI Keyとか載せていたのでどうにかしないとなということになりました.
そこでdotenv-railsで環境変数を扱うことにしました.
これを使うと, .envファイルに環境変数を書くだけで勝手にrailsのファイルから呼び出せます. ですが, ここでバージョンの問題が発生したのでそのメモ.
Gemfileに
として docker-compose run --rm web bundle install すると自分の環境だとdotenv-rails(0.7.0)が入りました. で, 仕様通りに使っても環境変数が呼び出せないと.
色々調べていくうちに, バージョンの問題が浮上しました.
というわけで, dotenv-railsを2018年8月現在で最新のバージョン2.5.0を指定して入れ直すことにしました.
dockerでのGemのアンインストールとGemfile.lockの更新は以下の感じです.
したあとで, Gemfileを以下に書き換えて
するとdotenv-railsが使えるようになります.
herokuにデプロイ
.gitignoreの設定
dotenv-railsを使って秘匿情報を切り分けましたが, デフォルトでは.envファイルが.gitignoreに書いてないので書きます. ついでにHerokuに上げる必要のないDockerfileとdocker-compose.ymlも載せときます.
Herokuにデプロイ
webpackerのデプロイに関する項目を読むと, Heroku側がいい感じにやってくれそうなので, 特別な設定なくいけます.
Heroku
Heroku installs Yarn and node by default if you deploy a Rails app with Webpacker so all you would need to do:
heroku create shiny-webpacker-app heroku addons:create heroku-postgresql:hobby-dev git push heroku master
で, webpack使っているので恐らくasset pipline使わない関係で, config/environments/production.rbの config.assets.compile = false にしないと警告出ます.
そしたらもう
で行けるかなと思ったのですがいくつかつまずいたのでメモ.
app/javascript/imagesに画像がなくてコンパイルエラー
webpackerのエントリポイントのファイルで require.context('images', true, /\.(png|jpg|jpeg|svg)$/) にしているのに画像がないため怒られました. 何でもいいのでこの拡張子の画像を入れておきましょう.
起動のコマンドがおかしなことになってた
今回develop環境ではforemanを使っていました. で, Procfileを書いてたんですが, ProcfileがあるとHerokuはここに書いてあるコマンドでアプリを起動させるみたいです. デフォルトだと bundle exec rails s -p $PORT -e $RAILS_ENV で起動するみたいなので, Procfileの中身を以下に書き換えます.
※ あまりよくわかっていないのですが, たとえProcfileを.gitignoreしたとしてもProcfileの中身が読み込まれます. なので, Herokuに上げる際は必ず書き換えたほうがいいでしょう.
※ もっと良いやり方あると思う...
config/environments/production.rb にdeviseメール認証の記述をしていない
開発環境では
を書いていたのですが, 単純にデプロイ側にこれを書いていなかったのでエラー吐かれました. なので, hostをデプロイ環境に合わせて
を記述します.
twitterのコールバックURLが開発環境の時のまま
twitter developmentの登録したアプリのところで, CallbackURLに
を追加しておけば動きました.
以上が無事済んだら
でOKです. データベース情報は, PG Commander の設定に入れてやれば接続できます.
これから
今後もデプロイでつまずきそうなので, 気をつけながらやっていきたいです.
※ 追記
ちなみにdockerでもデプロイできるみたいなので, 余力があればやろうかな.
Rails+React axiosで通信 ~CSRFトークンの設定~
前回RailsとReact間でaxiosを使ってajax通信をしたのですが, GETメソッドは特別な設定なくできました. しかし, POST(GET以外)は設定しないと動かなかったのでそのメモです.
CSRFとは
CSRFとは Cross-Site Request Forgeries の略で, ユーザの意図しない動作をさせる攻撃です.
情報処理推進機構:情報セキュリティ:脆弱性関連情報の取扱い:知っていますか?脆弱性 (ぜいじゃくせい)/3. CSRF (クロスサイト・リクエスト・フォージェリ)
例えば, AさんがあるSNSにログイン中に悪意のあるサイトを見たとします. そして悪意のあるサイトの罠が仕掛けられたリンクをクリックすると, あたかもAさんがリクエストを出したように, 悪意のあるサイトからログイン中のSNSにリクエストが飛びます. すると例えばアカウントを削除されたりなんなり, 色々悪用されてしまうと言ったことが起こります. これがCSRFです.
RailsとCSRF対策
RailsにはCSRF対策が施されていて, 悪意のあるサイトからのリクエストか, 自分のプログラムからのリクエストか判別できるような仕組みが用意されています. Railsでは, GETリクエストはそこまで破壊的な処理がなされないと考えているのか, 対策なくaxiosで通信できるのですが, POST, PUT, DELETEでは致命的なダメージを与えると考えているらしく, CSRFトークンと呼ばれるパスワードみたいなものの設定が必須になっています.
Rails側で用意されているヘルパーメソッド(form_forとか)にはデフォルトでこのCSRFトークンが設定されているので気にせずPOSTとかできてましたが, フロントエンドとサーバーサイドを分けて通信する場合には意識しなければなりません.
上記サイトによると,
検証を通すには「authenticity_token をフォームに埋め込んでおく」か
「X-CSRF-Token をリクエストヘッダーに設定しておく」
らしいです.
で, 今回の場合どうするかというと, rails-ujsというajax通信をよしなに行ってくれるライブラリのcsrfトークンを取得する機能を使って解決します. 具体的には,
これで送れます. コントローラ側ではparamsにjson形式で入っています. 詳しくはbinding.pryすればわかります.
今後
データベース構築かな....... 以外と一番考えなきゃいけないとこな気がします.
dockerでpry-railsを使う(デバッグ)
paramsとかみたいなーって思ったとき, dockerだと普通にpry-rails使ってbinding.pryできなかったのでそのメモです.
docker-compose で pry-rails を使う
https://stackoverflow.com/questions/35211638/how-to-debug-a-rails-app-in-docker-with-pry
上記の記事を参考にしました.
すると, 一見何も変化がないんですが, binding.pryのとこに来るとpryしたときの, いつもの感じのコンソール画面になります. で, コンソールには表示されないんですがキーボードを打ってEnterを押すとみれます.
ちなみに抜けるときは exit で.
Rails+React with webpacker twiiter認証してタイムライン表示
TwitterでOmniAuthやってみたのでメモしておきます.
Twitter認証とタイムライン表示
下記サイトを参考にしました.
導入したgemは
基本的に上記サイトの通りでやりました. omniauth入れておくと, auth/twitterにリンク飛ぶとよく見るtwitter認証画面に飛びます. で, 認証するとcallbackで指定したリンクに飛ぶと...
つまったこととしては, twitter development(https://developer.twitter.com/)サイトのアプリ登録のとこですね.
アプリ登録する際, CallbackURLを設定しますが, 上記サイト通りのルーティングだとhttp://127.0.0.1:3000/auth/twitter/callbackにしないといけません. localhostは拒否られます.
で, localで作業するとき,localhost:3000とかするとコールバックしたときにエラー吐かれるので, 最初からhttp://127.0.0.1:3000にアクセスしないといけませんでした.
今後
twitterのプロフィール画像とかも取得したいと思います. あとdeviseとも連携させたいな.
追記
した場合, ユーザの基本的な情報は,
client.user.********
の********に下記サイトのやつを引っ張ってくれば良い.
(ex.) id なら client.user.id
Rails+React with webpacker データベースをReactでいじる
前回まででReactをRailsで使う環境は整いました.
でも, Reactでデータベースの値をどうやって参照すればいいのかつまづいたのでメモしておきます.
ルーティングとコントローラ設定, axiosでReactと通信
webpackerのファイルの構成は割愛します. 自分は app -> javascript 配下に
のような感じで置きました.
そして docker-compose run --rm web rails g controller home でhomeコントローラ作成しました.
そして, app/config/routes.rb を以下のように設定.
こうすることで, Reactコンポーネントからaxiosで /axios_get にアクセスするとhomeコントローラのgettingメソッドが呼ばれる. なのでgettingメソッドのから値を返してやれば良い. homeコントローラは以下.
ここではTodoというモデル(todosテーブル)を作ってデータベースの値を引っ張ってきています. で, 返り値はjson形式です.
(一応layout指定してますが, 無くても勝手に読んでくれる???)
最後にReact側で
みたいに書けばコンソールのログにデータベースの値がJSONで入ってます.
※ 初歩的ですが, Reactのクラス名は大文字英字で始めないとエラーになります(一回やった笑)
これから
次はデータの取り扱い方を詳しく見ていこうかなと. あとpostもしようかなと.