2011年6月16日木曜日

Yahoo!にログインする際に文字認証が出る原因およびプログラムからログインする方法

以前、「プログラムからYahooにログインする際に、不正アクセス防止機能により文字認証画面が出た時の対処法」の記事でご紹介した通り、5/19頃よりYahoo!JAPANのログイン時に、状況によって、以下の画像のような文字認証の画面が出るようになっていたのですが、昨日6/15より、この条件がまた変更になったようです。



私が担当している仕事でも、プログラムでのYahoo!へのログイン部分に影響が出たため、原因と対処法を急遽調査しました。

その結果、分かったことは以下の通りです。

まず、ログイン時に文字認証が出てしまう条件は、

1) ブラウザにYahoo!のログイン関係のクッキーが保存されていない状態(ブラウザの設定でクッキーの保存期間を「ブラウザを終了するまで」に設定している場合など)で、直接Yahoo!のログイン画面にアクセスし(ログイン画面をお気に入りに登録している場合など)、ログインしようとした場合

2) ログイン時にJavaScriptをオフにしている場合

のどちらかに当てはまる場合のようでした。

したがって、

1) JavaScriptはオンにする
2) ログインする時には、いきなりYahoo!のログイン画面にアクセスせず、いったんYahoo!トップページにアクセスして、そこにある「ログイン」リンクからログイン画面にアクセスするか、あるいは、マイオークションのようなログインが必要なコンテンツをお気に入り登録しておいて、そこにアクセスすることによって表示されるログイン画面からログインするようにする

の2点を守れば、文字認証が出ずに済むことになります。


一方、プログラム(perl/phpなど)からYahoo!にログインする場合ですが、基本的にはブラウザからログインする時と同じ手順を踏めばOKです。

以前なら、ログインURLにIDとパスワードをPOSTするだけでよかったのですが、今は、ログインフォームにhiddenタグで埋め込まれているパラメータも全て拾って投げるようにしてください。

ただし、パラメータをそのまま投げてしまっては、JavaScriptをオフにしているのと同じ状況で文字認証が出てしまい、そこから先に進むことができません。

とはいえ、ログインフォーム上でJavaScriptがやっていることは、現時点では単純で、パラメータの一部を変更しているだけなので、ログインフォームのHTMLソースをよく見れば、対処法はすぐに分かると思います。

本当は、perlなりPHPなりのサンプルソースを載せればいいんですが、あまり詳細に書きすぎると、Yahoo!に迷惑をかけることになるかもしれませんので...

もし、どうしても先に進めない方がおられたら、コメント欄にご記入ください。
何らかのアドバイスを差し上げられると思いますので。

[2011/10/19 追記]
本日夕方頃より、上記のやり方でプログラムを実行した時に、また文字認証が表示されるようになってしまったようです。
色々手探りで調べたところ、ログインフォームを取得してから、ログイン情報をPOSTするまでの間に、3秒くらい間をあけると、文字認証が出なくなりました。
同様の現象に遭遇された方は、試してみてください。

関連記事


ブログランキングに参加しています。
最後に応援クリックしていただけると、とても嬉しいです!

52 件のコメント:

匿名 さんのコメント...

こんにちわ。同じ現象でハマっております。PHPプログラムからのログインCookieを取得したいのですが、どうしても文字認証画面になってしまいます。
hiddenタグは全て折り返しています。
そして、一部のパラメタはJSでコソっとしている模様で、それも同じパラメタになるように細工しました。
でも、まだ文字認証現象から回避できません。js で小細工しているのは、1つだけですよね? .a???????? の細工だけどと思うのですが、いかがでしょうか?もう少しヒントを頂けると助かります。cookieに何か秘密があるのでしょうか?

knw さんのコメント...

コメントありがとうございます。
jsでの細工は、その通りです。

あと、思いつくこととしたら、UserAgentの設定はされていますか?
UserAgentが実在するブラウザのものになっていないと、文字認証が出てしまうようです。

匿名 さんのコメント...

返信頂きましてありがとうございます!
なんとか、成功しました!!
仰るとおり、User-Agentがウソっぱちでした。
それと、ログインPOSTまでのリクエストの総数は3回ですね。。。
ログインページをcookieなし状態から1度開いて、そこで "B" をセットして再リクエスト。。。その後、ご教示頂いた細工をコチョっとしてからPOSTしたら成功しました!!
(T-T)ありがとうございました。

knw さんのコメント...

そうですね、ログインまでに、

1) Yahoo!トップなどどこかのページでクッキーBを取得
2) ログイン画面にアクセスして、hiddenに埋め込まれているパラメータを取得
3) ID,パスワード情報を追加し、パラメータの一部を変更して、POST

という3リクエストが必要になります。

うまくいったようで、よかったです(^^)

匿名 さんのコメント...

皆様と同様、昨夜より徹夜で難儀しておりました者です。ヒントを頂いたお陰で修繕も終わり、今日は帰れそうです。ありがとうございました。ちなみうちはjavaでした。それでは失礼致します。

knw さんのコメント...

コメントありがとうございます。
修繕完了とのことで、よかったですね。
少しでもお役に立てたのであれば、何よりです。

不正アクセス対策ということで、予告無しに仕様変更されるので、対応が大変ですよね。

この後しばらくは何もなければいいのですが...

匿名 さんのコメント...

貴重な情報をたいへんありがとうございました。Yahooの細工にまるで気付きませんで、こちらを拝見していなければ対策を投げ出してしまっていたと思います。
おかげさまで無事、対策を終えることができました。
本当にありがとうございました。

knw さんのコメント...

コメントありがとうございます。

こういう情報を載せることが、不正アクセスをしている人の役に立ってしまうかもしれないので、ちょっと悩む部分もあるのですが、一方で正当な利用者で困っている方と情報共有したいとの思いもありますので、これからも情報提供を続けていきたいと思います。

Yahoo!さんには、不正アクセス者のみをシャットアウトできるような、何かうまい方法を考えて頂けるとうれしいですね。

IPごとのログイン成功率ではじくとかだめでしょうかね。

tichi73 さんのコメント...

perlのWWW::Mechanizeを使った自作スクリプトが6/15からログインに失敗していたのを調べていて、このページにたどり着きました。ログインフォームのjsを見てすぐ対処法わかりました、ありがとうございます!

むしろ、フィールドの名前がドット '.' で始まっているので mech->field() で値を設定しようとしたときに正しく INPUT フィールドが選択できず(class 名で検索してしまう)にすこしハマりました。

HTML::Form のヘルプを見て、セレクタにプレフィックス '^' をつければよいことに気がついて無事解決しました。

knw さんのコメント...

tichi73さん、コメントありがとうございます。
このページがお役に立てたようで、よかったです(^^)

また、HTML::Form特有の問題についても教えていただき、ありがとうございました。

匿名 さんのコメント...

login方法変えるのはいいけど、対処法などの説明は載せるべきだと思いました。そこがyahooはちょっと不親切です。

匿名 さんのコメント...

こんばんは。
今日の夕方から文字認証が必須になってるようなのですが・・・。
私だけでしょうか?

匿名 さんのコメント...

自分も今日初めてひっかかりました!

匿名 さんのコメント...

この記事のおかげで問題を解決することができました。ありがとうございます。

knw さんのコメント...

みなさん、コメントありがとうございます。

まず、「6/17の夕方から文字認証が必須になった」という件については、ブラウザでログインした時の話でしょうか、それともプログラムでログインした時の話でしょうか?

私の環境では、今回改修したプログラムで今もログインできているので、もしかすると、どこか細かいところで変更があったのかもしれませんが、ちょっとよく分かりません。

そういえば、同一IPから複数のアカウントを切り替えてのログインを繰り返すと、一定時間文字認証が必須になってしまう現象は見たことがあります。
この場合は、一定時間放置しておくと、また復活するようです。

それから、Yahoo!が今回の改修の件について説明をしない件に関しては、たしかに不親切と思います。

ただ、おそらくは今回の改修の目的が、プログラムから大量のログインを試して、他人のアカウントを盗もうとする行為への対応だと思われますので、公に説明するわけにもいかなかったのでしょうね。

最近Yahoo!のAPIでも、認証の仕組みを備えたものが加わっているようなので、APIを介さずにアクセスしているプログラムについては、あくまでも自己責任、何の保証もしませんよ、ということだと思います。

とはいえ、なんせYahoo!の全サービスに関わる改修ですから、相当たくさんのプログラムやサービスが影響を受けたでしょうね。

これから先も色々対応は打ってくるでしょうが、できれば不正アクセス者に限定した対応をしてくれるといいのですけどね。

匿名 さんのコメント...

firefoxを使ってて急に文字認証になったのでウイルスに感染したのかとあせりました(^^;)
両方の条件に当てはまっていました。
貴重な情報ありがとうございました。

knw さんのコメント...

コメントありがとうございます。

今回の件は、突然のことだったので、普通にブラウザを使っている方でも、結構戸惑われた方が多いみたいですね。

お役に立てたようで、よかったです(^^)

匿名 さんのコメント...

作業を効率化するために自作スクリプトでログインして情報を取ってくる事をしていましたが、
今回の変更でログインできなくなりました。
自作スクリプトといっても知識がないのでWgetを使って行っていますが、
このページとコメントをヒントにやってみたらアッサリいけました。ありがとうございます。
jsも読めないですが、単純な事しかしていない様だったので助かりました。
jsの部分の細工が更に変更されたらjsを習得しないとダメですね。

knw さんのコメント...

コメントありがとうございます。

たしかにJSでやっていることが複雑になると、対応が大変になりそうです。

できれば、そうならないでほしいですね(^^;

匿名 さんのコメント...

たすけてください〜 --;

わからなすぎて頭から火が出そうです。

.a******** をごにょっとして
.n*** を送らない

で間違えないでしょうか。

それとクッキーBは
$cookies = $request->getResponseCookies();
だと取得出来るのが↓こんなに短いんですけど
3c4ln6571hXXX&b=3&s=mu

これで問題ないのでしょうか?

Live HTTP headers で見るともっと長いんですけど...

よろしくお願いします。

匿名 さんのコメント...

ごにょごにょしたら解決しました。
ありがとうございました。

匿名 さんのコメント...

初めまして。記事の内容を参考にさせていただいております。

2点質問させてください。

1 .a********の値について
みなさん簡単にごにょごにょされているようですが、細工前と細工後の値を見比べても私にはやり方がわかりませんでした(涙
javascriptコードから細工後の値を取得することもできますが、みなさんはどう処理されてるのでしょうか?

2 Bクッキーについて
上の方からも質問が出ておりますが、プログラム(java)で取得したBクッキーの値がLive HTTP headersのものと違いだいぶ短くなっています。
Bクッキーについても何か特別な処理が必要なのでしょうか。


お忙しい中恐縮ですが、よろしくお願いします。

knw さんのコメント...

コメントありがとうございます。

ご質問の件ですが、まず「1 .a********の値」については、自分で変換するのではなく、javascriptコードから細工後の値を抜き出して、それをPOSTする時に使えばOKです。

それから「2 Bクッキー」については、特に処理は必要ありません。
たしか1アクセス目では短いのが返ってきて、2アクセス目で長いのが返ってきたような記憶があります。

以上で試してみてください。

knw さんのコメント...

7/10にコメント下さった方、返信できず、すみませんでした。

無事解決されたようで、よかったです。

匿名 さんのコメント...

7/19に書き込んだ者です。

お蔭様でログインできました。

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

匿名 さんのコメント...

PEAR:HTTP_Clientを使用したヤフーへのログイン処理を記述していて、ここにたどり着きました。
おかげさまで文字認証を回避することができ、感謝しております。

knw さんのコメント...

コメントありがとうございます。

お二方とも、無事解決されたようで、よかったです(^^)

匿名 さんのコメント...

以前、ここの管理者様に助けて頂いた者です
(2011年6月16日12:00 )
今回のYahoo側の変更の対応として、PHPコードになりますが、

sleep(3);

をかましたら、ログインできるようになりました!!!
毎度毎度、貴重な情報を提供いただきありがとうございました!!!

ちなみにですが、、、
sleep(2);
sleep(1);
でも大丈夫でした。。。

knw さんのコメント...

コメントありがとうございます。

またお役に立てたようでよかったです(^^)

sleepする時間については、私も1秒も試してみたのですが、ログインに成功する時と失敗する時があったので、大事を取って3秒にすることにしました。

この辺り、ちょっとアバウトな対応なので、今後どうなるかちょっと分かりませんが...

匿名 さんのコメント...

今回ログイン出来なくなり、
5月にここを見たのを思い出しまた拝見させて頂きました。
まさか時間だとは・・・。

毎度助けて頂いております。
貴重な情報を有難うございました。

匿名 さんのコメント...

前コメント6月のtypoです。失礼しました。

匿名 さんのコメント...

私もこちらの情報に助けていただきましたので、一言お礼を申し上げに来ました。以前もこちらの情報を参考にさせていただきました。

C++で作成した通信処理でまたしてもログイン不能となったのですが、今回はeclipse上でブレークポイント設定してデバッグすると、なぜかログインOKだったので不思議に思ってました。ウェイト時間の情報が大変参考になりました。3秒はログインシールを見るための時間ということなんでしょうね。

貴重な情報をタイムリーに教えていただきありがとうございました。

tks

knw さんのコメント...

みなさん、コメントありがとうございます。

たくさんの方のお役に立てたようで、うれしいです。

今回もなんとか問題解決することができましたが、次回はどうなることやら...

匿名 さんのコメント...

knwさん はじめまして

9月の末頃にこのページの情報を参考させていただき、無事ログインできるようになりました。改めまして御礼いたします。

さて、今回もまた参考にさせていただき、ログインフォーム取得~POSTまでにsleepさせてみたのですが、文字認証画面になってしまい、ログインできませんでした。

eclipse上でブレークしながら確認してみたのですが、状況は変わらないようです。
今朝になってまた状況が変わったりしているのでしょうか?


大変申し訳ないのですが、現状をお教えいただないでしょうか?

knw さんのコメント...

コメントありがとうございます。

状況を確認したところ、こちらの環境では、今朝も特に問題なくログインできているようです。

ですので、プログラムのどこかに問題があるか、あるいはIPアドレスで一時的な制限をかけられているのかもしれません。

匿名 さんのコメント...

knwさん

先ほど現状をお聞きしたものです。

早速のご返信ありがとうございました。


では、プログラムをもう一度見直してみます。迷いが晴れました。(^_^A;

IPアドレスで一時的な制限もあるのですね!
今回は同一PC上でブラウザを使用した場合は問題なくログインできるので、多分プログラムの一部に問題があるのだと思いますが…

お忙しい中、ありがとうございました。

匿名 さんのコメント...

knwさん

ご連絡が遅くなり申し訳ありません。
先日、ログインできないと書き込んだものです。

あの後でバックアップより回復したソースにsleepを追加したソースで無事にloginできました。
やはり、ソースの変更時に何か問題を作り込んでしまった様です。お騒がせしました。

knw さんのコメント...

コメントありがとうございます。

無事ログインできたとのことで安心しました。
わざわざご連絡くださり、ありがとうございました。

匿名 さんのコメント...

3秒Waitは盲点でした。
ここ見なかったら延々と悩んでいるところでした。
感謝です。

匿名 さんのコメント...

こちらの問題にとても詳しいようで手伝っていただけないでしょうか。。。
様々な方法をやってみたのですが、結果的に画像認証の画面が出てしまい、ログインできない状態です。何か手がかりなるアドバイスをいただけませんか。良かったらご自分で使っているコードの一部でもお見せできませんか。よろしくお願いいたします。
こちらのやり方としては、
1-auction.yahoo.co.jp にアクセス cookie 保存('B'というやつ)
2-https://login.yahoo.co.jp/config/login?.lg=jp&.intl=jp&.src=auc&.done=http://auctions.yahoo.co.jp/ にアクセス login formからPOST parameters 取得
3- form POST
4-画像認証の画面。。。

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

knw さんのコメント...

コメントありがとうございます。

ログインできないとのことで、まずは以下の3点を確認していただけますでしょうか。

1) 適切なUserAgentを設定しているか(実在しないブラウザのものを指定していると、はじかれます)

2) 2.で取得したPOST parameterの内、「.albatross」という名前のパラメータの値を、置き換えているか
(ログイン画面のソース内にあるJavaScriptでやっているのと同じ置き換えをしてください)

3) 2.のパラメータ取得から、3.のform POSTまでの間に、3秒程度の時間をあけているか(すぐにPOSTするとはじかれます)

よろしくお願いします。

匿名 さんのコメント...

回答ありがとうございます。大変助かりました!
②はjsから取るんですね・・
②はyahooのPOSTフォームから取得してからログインしようとしてました・・

ありがとうございました!最初からもうちょっと頭を使えばよかったのに・・

knw さんのコメント...

無事ログインできるようになったということでしょうか?

もし、そうだったら、よかったです。

また、何かあればお気軽にお問い合わせくださいね。

匿名 さんのコメント...

できましたよ。おかげさまで ;)
作ったスクリプトはウェッブページで使うつもりで、目的としてはサイトにログインしたユーザーさんがいつでもヤフー(私のアカウント)にアクセスできるような仕組みになります。クッキーをファイルに保存して、期限有効なクッキーでしたらそれを使いそのままログイン、期限が切れていたら新しいものを取得してからログインする か スクリプトが呼び出されたたびに一々ログインする。
自分的にはクッキーをファイルに保存してそれを使ったほうが良いと思いますが(ヤフーBクッキーが3日以内有効のようで)、それはあんまり望ましくないという声も聞いています。

ご意見いただけないでしょうか。
よろしくお願いいたします。

knw さんのコメント...

お返事遅くなってすみません。

私が作っているシステムでは、クッキーはファイルには保存せず、スクリプトが呼び出されるたびにログインしています。
現状、それで問題はないようですが、ログインの頻度によっては問題になるかもしれません。

ちなみに、そのスクリプトは1日に何回位呼び出されると想定されているでしょうか?

匿名 さんのコメント...

こんにちわ。またこの問題が復活したみたいですね。皆さん解決方法を見つかりましたでしょうか?
よろしくお願いいたします。

knw さんのコメント...

情報ありがとうございます。

ただ、こちらで試した限りでは今までの方法でうまくいくようです。

IPアドレスで制限されることがありますが、別のIPアドレスからでも、うまく行かないでしょうか?

匿名 さんのコメント...

Yahooログインで見た変な文字認証
ちんもをもむ

特に意味は無いんだろうが馬鹿馬鹿しい文字認証は一体誰がプログラミングしてるんですか?

匿名 さんのコメント...

初めまして。
PHPでYahoo!にログインできないかと情報を求め、ここにたどり着きました。
こちらの情報が公開されてからだいぶ時間が経っていますが、
今もこの手法は有効でしょうか?

ゴニョゴニョなどを何とか読み取りトライしているのですが、
ログインできないようなのです。
三段階アクセスの最後のfile_get_contents()の結果は、
ログインしていない状態のYahoo!のトップになります。

三段階アクセスをせずに、いきなりloginとpasswdをPOSTすると、
文字認証画面が出ます。

ですので、三段階アクセスはそれなりに機能しているように見えるのですが、
結果はログインされいない、という状況なのです。

もし、何か状況が変わった等あれば、情報を頂戴できると助かります。
よろしくお願いします。

匿名 さんのコメント...

上の者です。
クラス化して公開なさっているのを見つけました。
http://comeonly.hatenablog.com/entry/20120702/1341218892

こちらを使ったら、あっさり、ログインできました。
やってることは、まずは、クッキーを取得して、
hiddenをかき集め、.a***をすり替えて、.n***を抜き、
3秒ルールを適用して、という具合にこちらと同じようです。

ということで、私のが動かなかかったのは、
どこかに間違いがあるということですね。
はっきりして良かったです。
お騒がせしました。

knw さんのコメント...

コメントありがとうございます。
問題解決されたようでよかったです。
何かあればまたお気軽にご質問ください。

匿名 さんのコメント...

上の者です。
公開されているクラスを使わずに、
自力でも上手くログインできました。

というか、ログインは前からできていたようで、
その後のアクセスの仕方がまずかったのが原因でした。

ログインした際に返ってきたクッキーを取りこぼしていました。

というバカバカしい原因でした。
一応、報告まで。