質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OAuth

OAuth(Open Authorization)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Facebook

Facebookは、実名登録制のSNS(ソーシャル・ネットワーキング・サービス)です。開発者用のデベロッパーサイトが存在し、一般ユーザーによるFacebook向けアプリケーション開発が可能です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

3回答

4685閲覧

CakePHPからRailsへ焼き直す際に、ユーザー認証がうまく移行できない

ooo

総合スコア22

OAuth

OAuth(Open Authorization)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Facebook

Facebookは、実名登録制のSNS(ソーシャル・ネットワーキング・サービス)です。開発者用のデベロッパーサイトが存在し、一般ユーザーによるFacebook向けアプリケーション開発が可能です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

1クリップ

投稿2015/04/16 10:33

今回、既存のWebサービスをCakePHP2.xからRails4.xへ焼き直そうとしています。

その際、登録済みのユーザー様については、同じe-mailとパスワードでログインして頂きたく、
Usersテーブルのデータをそのまま移行できないかと考えているのですが、
CakePHPで暗号化したパスワードを、どのようにRailsで突合すればよいのかわからず困っています。

このような場合の移行方法をご教授頂ければ幸いです。

いま、Railsのログイン処理にはdeviseを利用する予定で、CakePHPでは以下のようにパスワードをハッシュしています。

lang

1 public function hash($password) { 2 return password_hash($password, PASSWORD_DEFAULT); 3 } 4 5 public function check($password, $hashedPassword) { 6 return password_verify($password, $hashedPassword); 7 }

http://qiita.com/hmuronaka/items/73fb9f2986a46905ff3d

ちなみに、こちらのURLの情報を参考に作業してみたのですが、うまくいきませんでした。
そもそもSaltについての理解ができていないのですが、少し調べてみたところ、
私のソースの場合はランダムでSaltを生成するため、
上記URLのようにSaltを固定する場合の解決方法は当てはまらないのではないかと思っております。

※見当違いの解釈をしている可能性がありますが、下記URLの引用部分を読んでそう考えています。

http://php.net/manual/ja/function.password-hash.php

省略した場合は、パスワードをハッシュするたびに password_hash() がランダムなソルトを自動生成します。これは意図したとおりの操作モードです。

【Facebookについて】
なお、CakePHPで作ったサービスにおいてはFacebookログインも利用しており、
RailsではOmniauth-Facebookで、対応するつもりなのですが、
Facebook_uidも既存のものを引き継げないでしょうか。

こちらについては恐縮なのですが、現状本番への影響が怖く、
本番に利用しているFacebookAPP_IDとSecretでは未テストです。
APPとSecretが一致すれば、Facebook側から発行されるuidも一致するのでしょうか?

どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

Saltについての理解

ハッシュ関数は逆計算が困難ではあるのですが、たとえば「apple」のようなありがちなパスワードを使っていた場合にmd5ハッシュをとると 30c6677b833454ad2df762d3c98d2409 になります。 これでGoogle検索すると簡単に元の文字列appleが判明してしまいます。これはmd5に限らず大抵の汎用的なハッシュ関数に言えることで、saltを使わない場合の問題点です。
saltは後ろにサービス固有の文字列を追加することで、その逆計算を困難にする仕組みです。saltが十分に複雑な文字列だった場合、上のような簡単な方法でハッシュの逆計算は出来なくなります。
仮にハッシュ後の文字列が漏洩してもサービスにはログイン出来ないように、ということでこういったsaltを追加します。

大事なのは、設定する時も照合するときも同じsaltを使いっているのだ、と言う事です。そうしないとそもそもhash後の文字列が一緒にならない、認証出来ない、ということになってしまうわけです。
ですから、ランダムだから当てはまらないというのはおかしいです。 あなたのCakePHPのソースコードには、以前にランダムで生成した文字列が、ソースコードに固定で書かれているんじゃないですか?
さて、そういうわけで、昔ランダム生成した文字列をRails側にコピペして持ってきてしまいましょう。その上で先のQiitaの記事の通りにすれば上手く行くはずです。

Facebookの方ですが、理屈の上ではそうですが、テストしないと結構、危なそうですね。
DBの内容を引っ張ってきて、ローカル環境やステージング環境できっちりテストするのが良いと思いますよ。

投稿2015/04/16 10:55

AknEp

総合スコア200

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ooo

2015/04/16 11:06

ご回答いただきましてありがとうございます! >>設定する時も照合するときも同じsaltを使いっているのだ、と言う事です。そうしないとそもそもhash後の文字列が一緒にならない、認証出来ない、ということになってしまうわけです ここについて、AknEpさんのおっしゃる通りだと思っていたため、 自分のSaltの理解について納得がいっておりませんでした。 というのも、「ハッシュのたびにSaltをランダムで生成するなら、照合するときどうやってるんだろう•••」と、質問文中で引用しているPHPマニュアルの以下の部分を読んで混乱しておりました。 "省略した場合は、パスワードをハッシュするたびに password_hash() がランダムなソルトを自動生成します。これは意図したとおりの操作モードです" >> あなたのCakePHPのソースコードには、以前にランダムで生成した文字列が、ソースコードに固定で書かれているんじゃないですか? これはまさにそうです! やはり固定Saltを利用するということで間違いないようで、 前回照合に失敗していたのは私の手順にミスがあったんでしょうね。 これで安心して試行錯誤できます!ありがとうございます! Facebookについては本番デプロイ前に、 必ずステージング環境でテストするようにしますね。 とても困っていたので、素早いご回答を頂けて助かりました! 本当にありがとうございました!
ooo

2015/04/16 12:49

【追記】 Lohn様のご回答が解決に直結していたため、 大変恐縮ですがベストアンサーを振り替えさせていただきました。 重ね重ね、ご回答頂きましてありがとうございました!
AknEp

2015/04/16 12:51

Lohnさんの回答が気になって調べてみたところ、勘違いがあったのが解りました。少し補足します。 結局CakePHPでもRailsでもsaltは固定値なようで、ちょっと余談ではあるのですが。 PHPの password_hash() ではランダムなsaltを使ってハッシュ化を行い、その返り値は"ハッシュ値<ドット>ハッシュ化に使ったランダムなハッシュ値" という文字列を返し、password_verifyはその文字列を受け取るとランダムハッシュ値を利用して有効かどうかの確認をしてくれるみたいです。 何にせよ、処理系が違うこともあり、ちょっとしたオプションの違いでマッチしなくなる事が予想されますね。(しかもCakeもRailsのDeviseも内部のブラックボックスに押し込まれてるから追いかけるのがちょっと大変です)慎重にがんばってくださいね。
ooo

2015/04/16 13:16

>>PHPの password_hash() ではランダムなsaltを使ってハッシュ化を行い、その返り値は"ハッシュ値<ドット>ハッシュ化に使ったランダムなハッシュ値" という文字列を返し、password_verifyはその文字列を受け取るとランダムハッシュ値を利用して有効かどうかの確認をしてくれるみたいです。 ご丁寧にありがとうございます! なるほど!!php側のverifyメソッドでハッシュ値の有効性を確認してるんですね。 ということはブラックボックスに手を突っ込まない限り、 rails側のauthenticate_phpが完全にphp5互換していることを信じて進むしかないんですね•••笑 既存データに関してはバッチでもまわして全件テストしてみようと思います! ありがとうございました!
guest

0

ベストアンサー

Saltについて

まずは、ご自身が利用されている暗号化方式について確認されるのが良いと思います。
※現行のCakePHPでは、BCrypt(Blowfish)を利用しているのだと思いますが、qiitaのリンク先を見たところSHA/MD5を使用していますね。

BCryptのソルトとSHA等のソルトはそもそも概念が違うので、混乱する元になっていると思います。
(BCryptにはSHA等のソルトと同様の、ペッパーという概念はありますが)

BCryptについては、下記のページが参考になると思います。
http://www.kamiya54.info/post/100503173956/bcrypt-blowfish
http://php.net/manual/ja/faq.passwords.php

Deviseでは、デフォルトでBCryptを使用するようになっています。
パスワードが一致するかを試す場合は、以下のような方法で簡単に確認することができます。

lang

1BCrypt::Password.new( "CakePHPで暗号化済みのパスワード" ) == "password"

なおDeviseで使用するためには encrypted_password カラムに暗号化されたパスワードを保存する必要があります。

Facebookについて

こちらは割愛します。

投稿2015/04/16 11:31

lohn

総合スコア93

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ooo

2015/04/16 12:46

ご回答いただきましてありがとうございます! はい、既存データの形式を見る限りBCrypt(Blowfish)を利用しておりました。 Bcryptのソルトはまた別物なのですね•••参考に貼って頂いたリンクで完全に理解できました。 本問題の解決に直結していたので、恐縮ながらベストアンサーとさせて頂きました。 クリティカルなご回答に頭が上がりません。 大変助かりました、本当にありがとうございます!
guest

0

結論としては、cakephpで作成されていたBCryptパスワードは$2yアルゴリズムで作られていましたが、
Rails側のBCyrptのデフォルト認証アルゴリズムは$2aだったことが原因でした。
解決方法は、Cakeで作成されたパスワードの$2y部分を、$2aに直接書き換えるだけです。
これで認証されるようになるのも驚きましたが、大丈夫なようです。
なので、以下SQLを流して完了でした。
UPDATE users SET encrypted_password=REPLACE (encrypted_password,"$2y$10","$2a$10");

例)
Cakeで作成されたパスワード
$2y$10$amONVVOTZP3rqIzbYnVHyuzbIFZ/fzPY/il4qPMNBbJlUoQyGVTm2
RailsのBCrypt::password.newで認証成功するパスワード
$2a$10$amONVVOTZP3rqIzbYnVHyuzbIFZ/fzPY/il4qPMNBbJlUoQyGVTm2

お二人に頂いた情報をもとに試行錯誤していた結果、以下のページに辿りついたので、
参考までにURLを貼っておきます。ありがとうございました。

http://stackoverflow.com/questions/20980859/using-bcrypt-ruby-to-validate-hashed-passwords-using-version-2y

投稿2015/04/17 06:10

編集2015/04/17 06:25
ooo

総合スコア22

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問