てくのろーぐ

新卒エンジニアの日常ログ

rails5APIモード以外でCORS対策

CORSとは何かという方はこちら

Failed to load https://hogehoge: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://hogehoge' is therefore not allowed access

というエラーが表示されてAPIが叩けないという問題を解決する方法です。

環境

  • Rails5.01
  • Ruby2.4.1

方法

gem 'rack-cors' というgemを使いクロスサイトアクセスができるようにします。 このgemはRailsAPIモードを選択した場合、最初から記述されているものなので心配はないと思います。

rack-cors

httpsのOPTIONS メソッドに対してレスポンスを返すようになる。(preflightリクエストはOPTIONメソッドを使用) そのために routes.rbで設定をする必要はありません。 以下の記事ではこのgemを使わない方法で実装しています。 Rails APIでクロスドメインとpre-flight対応 - Qiita

使い方

  1. Gemfileに追加しインストール
gem 'rack-cors' 
bundle install
  1. cors.rbのコメントアウトを解除
# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'example.com'

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

これだけでひとまずリクエストを処理できるようになります。

CORS

CORS対策が必要となりそうなのでまとめました。

CORSとは

Cross-Origin Resource Sharingの略で、異なる2つのドメイン間でAJAXの実行を許可しないというWebブラウザ上の制約(同一生成元ポリシー)で起こるクロスドメイン問題を解決するためのもの。 安全性を考慮した上でクロスドメインアクセスを実現するための仕様としてW3Cが策定。あくまでもWebブラウザの問題なので、それ以外のものには関係がない。

CORSリクエストについて

これにはシンプルなリクエストとprefiredリクエストと呼ばれるものがあり、以下の条件すべて満たしたもの以外はすべて後者となる。

  • HTTPメソッドがGET, POST, HEADのいずれか
  • HTTPヘッダにAccept, Accept-Language, Content-Language, Content-Type以外のフィールドが含まれない
  • Content-Typeの値はapplication/x-www-form-urlencoded, multipart/form-data, text/plainのいずれか

  • 各リクエス

    • リソースにアクセスするリクエストを送信

      シンプルにリソースにアクセスするリクエストを送信する。 CORSで必要となるリクエストヘッドが含まれている事以外は通常のリクエストと変わらない。

    • preflightリクエストが送信されるパターン

      preflightリクエスト→ クロスドメインアクセスが可能かどうかを確認するリクエスト HTTPヘッダを使用してクロスドメインアクセス制御に関する情報を事前にやりとりする。HTTPのOPTIONメソッドが使用される

参考

詳しく知りたい方は下記のリンクが一番いい記事だと思います。

dev.classmethod.jp

PHPSTORMアップデート後pushができなくなる

PHPSTORMの最新ver、2017.3.2にアップデートした際、急にgithubにpushできなくなる現象が発生しました。 ものすごく単純なことが原因だったのですが、地味にハマったのでまとめておきます。

現象

表題通りpushができなくなる。 logを見るとset upstreamと怒られているのですが、git remoteで確認しても設定はされていました。

原因

アップデートと同時にPHPSTORMのgithub設定が変わったようです。sshで接続していたのですが、tokenかhttps認証になっていました。

解決策

単純にhttps認証化かtokenを用いた認証に変えれば大丈夫です。 httpsに関しては言わずもがな、tokenを使用する方法に関しても既にいい記事があったため割愛します。

qiita.com

上記の記事のような設定で問題なくpushできるようになると思います。

詳細な設定に関しては英語の記事しかなかったため、またまとめようと思います。

webpack-dev-serverがCannot read property 'compile' of undefinedエラーを吐く

環境

状況

上記の環境で、bin/webpack-dev-serverを行った場合、以下のようなエラーが発生し起動に失敗する。

TypeError: Cannot read property 'compile' of undefined
    at addCompilerHooks (/Users/shiba/workspace/rails_vue_first/node_modules/webpack-dev-server/lib/Server.js:71:15)
    at new Server (/Users/shiba/workspace/rails_vue_first/node_modules/webpack-dev-server/lib/Server.js:81:5)
    at startDevServer (/Users/shiba/workspace/rails_vue_first/node_modules/webpack-dev-server/bin/webpack-dev-server.js:398:14)
    at processOptions (/Users/shiba/workspace/rails_vue_first/node_modules/webpack-dev-server/bin/webpack-dev-server.js:361:5)
    at Object.<anonymous> (/Users/shiba/workspace/rails_vue_first/node_modules/webpack-dev-server/bin/webpack-dev-server.js:504:1)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)
    at Function.Module._load (module.js:500:3)

原因

現在(2018/3/5時点)、webpackerがWebpack4.0に対応していないことが原因のようです。

解決策

対応がされるまで、webpack-dev-serverのバージョンを下げることでの対応となります。 以下のコマンドでダウングレードを行ってください。

yarn upgrade webpack-dev-server@^2.11.1

その後、もう一度bin/webpack-dev-serverを実行した結果、エラーが発生しなくなりました。

参考

github.com

Rubyにおけるグローバルマッチング

ruby正規表現を使ったマッチングにはmatchメソッドがありますが、/gオプションがないためグローバルマッチングができない。 scanメソッドはパターンが1つの正規表現の場合はグローバルマッチングとして使えるが下記のようなにグループを使用した場合、グループに含まれていないものはマッチング対象にならない。

text ='グーグル https://www.google.co.jp/ ヤフーhttp://www.yahoo.co.jp/'
p text.scan(%r{(http|https|)://[a-z0-9/.]+[/]?})

[["https"], ["http"]] # 結果

そのため、Rubyでグループを使用するグローバルマッチングを行う際には以下のようにする必要がある。

text ='グーグル https://www.google.co.jp/ ヤフーhttp://www.yahoo.co.jp/'
regex = %r{(http|https|)://[a-z0-9/.]+[/]?}

match_data = []
text.gsub(regex) do |data|
  match_data.push(data)
end
p match_data

["https://www.google.co.jp/", "http://www.yahoo.co.jp/"]  # 結果

追伸

上の正規表現がガバガバなのは仕様です。 rubyでURLを抜き出すときはURI.extractを使うのがいいと思います。

Apache2.4でサブドメインを設定する

Verによってやり方が変わっているみたいです。

環境

  • CentOS7.4
  • Apache2.4.6

 

VirtualHostの設定を行う

httpd.confに NameVirtualHost *:80 という記述を追加する必要があるという情報が多かったのですが、Apache2.4からは不要みたいです。

バーチャルホストはデフォルトで有効化されているみたいですね。

 

Virtual.confを作成する

conf.dフォルダにある.confフォルダを勝手に読み込んでくれるので、名前はなんでもOKです。

PATH /etc/httpd/conf.d/

VirtualHost *:80&gt;
ServerName blog.hoge.net #ホスト名
DirectoryIndex index.html index.php #アクセスされたとき最初に表示されるファイル(2つある場合は前が優先)
AddDefaultCharset UTF-8
DocumentRoot /var/www/html/blog/
&lt;Directory "/var/www/html/blog/"&gt;
AllowOverride All # 設定の上書きを許可
Options FollowSymLinks Indexes ディレクトリ内のファイル一覧を非表示に

他にサイトが有る場合も同様に書いていけばOKです。

CentOS7 Webサーバー構築ことはじめ

毎回調べなおしていたのですが、 この機会に備忘録として残しておきます。

アップデート

yum update

ユーザーの追加と設定

まず、ユーザーを追加してパスワードを設定

adduser user_name # ユーザー追加 passwd user_name # パスワード設定

追加したユーザーでログインできることを確認したあとでrootでログインすることを禁止

vi /etc/ssh/sshd_config
PermitRootLogin yes  → PermitRootLogin no に変更
追加したユーザにsudoを許可
usermod -G wheel user_name

このsudo権限を持つグループ wheelの由来は一説によればbig wheel(実力者)から来ているそうです。

htpdインストール,設定

yum install httpd # インストール
systemctl start httpd # 起動 
systemctl status httpd # 起動したか確認 activeならok

ブラウザでサーバーのIPアドレスにアクセスしてApacheの初期画面が表示されることを確認 表示されない場合は一概には言えないけど、とりあえずfirewallの確認をしてみる。

firewall-cmd --list-all //確認
firewall-cmd --permanent --add-service=http // なければ追加
firewall-cmd --reload  #再起動

servicesにhttpがなければ設定を追加して再起動

ドキュメントルートの権限設定

groupadd group_name

ドキュメントルートの編集を許可するグループを作成、必要なら作ったユーザーを追加しておく /var/www/htmlの権限を変更する

chown apache:group_name html
chmod 775 html

apachecmsからの編集を可能とするため(必要なければいらない)

SSH公開鍵認証設定

まずは鍵の生成(なければ)

ssh-keygen -t rsa

特に設定を変更しなければ以下が作成される

公開鍵: ~/.ssh/id_rsa.pub 秘密鍵: ~/.ssh/id_rsa

そもそもSSH公開鍵認証って何?って人はさくらのナレッジがわかりやすいからおすすめ

サーバーに公開鍵を登録

.ssh/authorized_keysに公開鍵を設置できたらOK。 VPSとか借りている人は管理画面から直接登録できたりします。 ssh-copy-idを使用して登録(MAC限定) そもそもHomebrew入れてないって人はいい機会だから入れよう

brew install ssh-copy-id[/code]
ssh-copy-id user_name@host_name # <span class="c1">-iで鍵を選べる

手動で登録 サーバにSSH接続して行う

mkdir .ssh # フォルダ作成
touch .ssh/authorized_keys # ファイル作成
chmod <span class="m">700</span> .ssh # 所有者のみ実行読み書き可
chmod <span class="m">600</span> .ssh/authorized_keys # 所有者のみ読み書き許可</pre>
クライアント側で実行
scp ~/.ssh/id_rsa.pub user_name@host_name # 鍵をサーバ-にコピー
ssh user_name@host_name
cat id_rsa.pub &gt;&gt; .ssh/authorized_keys #ファイルを既定の場所にコピー

パスワード認証を禁止に変更

パスワード認証廃止してセキュリティを向上

sudo vi /etc/ssh/sshd_config

PasswordAuthentication no ChallengeResponseAuthentication no に設定 再起動をかける

systemctl restart sshd

 

パスワードをキーチェインに登録(MAC)

いちいちパスワードを入れる必要がなくなって捗る

ssh-add -K ~/.ssh/id_rsa