PHPでnamespace内でExceptionをcatchするときは、エスケープシーケンス(バックスラッシュ)\が必要

PHP
スポンサーリンク

LaravelのPHPで、かなりハマってしまった問題。

 

スポンサーリンク

Laravelでソーシャルログインの認証拒否のテスト

 

Laravelでソーシャル認証を実装しました。

Laravelでソーシャル認証(Twitter, Facebook, Google)を実装してみた
Laravelでソーシャルログインを実装してみました。 Socialiteをインストールする まず、Laravelにソーシャル認証用のプラグインSocialiteをインストールします。 Socialiteをインストールする方法...

 

 

LaravelのControllerでコールバック内では、以下の通りに実装しました。

これで、Exceptionが発生してもcatchしてリダイレクトされるはずです。

 

 

早速実験してみます。

ソーシャルログイン時に以下の記事出てくる画面が表示された場合、Twitter、Facebook、Googleでログインを拒否したとします。

Twitter, Facebook, Googleでアプリケーションの連携を解除する
Twitter, Facebook, Googleといったユーザーのアカウントを使って、他のWEBサイトにログインする、いわゆるソーシャルログインが流行っていますね。 ↓こんなやつです。 いちいち新しいアカウント...

 

すると、それぞれ次のエラーが発生します。

 

Twitterで拒否した場合

Twitterで拒否してみます。

・https://(url)/auth/login/callback/twitter?denied=xxxxx

InvalidArgumentException in TwitterProvider.php line 15:Invalid request. Missing OAuth verifier.

 

 

Facebookで拒否した場合

Facebookで拒否してみます。

・https://(url)/auth/login/callback/facebook?error=access_denied&error_code=200&error_description=Permissions+error

 

ClientException in RequestException.php line 107:Client error: GET https://graph.facebook.com/oauth/access_token?client_id=ccc&client_secret=ddd&redirect_uri=(url) resulted in a 400 Bad Request response:
{"error":{"message":"Missing authorization code","type":"OAuthException","code":1,"fbtrace_id":"xxx"}}

 

 

 

Googleで拒否した場合

Googleで拒否してみます。

・https://(url)/auth/login/callback/google?error=access_denied

ClientException in RequestException.php line 107:Client error: POST https://accounts.google.com/o/oauth2/token resulted in a 400 Bad Request response:
{
"error" : "invalid_request",
"error_description" : "Missing required parameter: code"
}

 

 

 

これ、全部、以下の関数の呼び出し元でExceptionが発生しています。

$user = Socialite::driver('twitter')->user();

 

ちゃんとTry~CatchでExceptionをCatchしているのに何で????

 

 

PHPでネームスペース内で例外をキャッチするときは、グローバルスペースにエスケープしないとダメ

調べてみるとちゃんと書いてありました。

When catching an exception inside a namespace it is important that you escape to the global space:

 

私の不勉強で、PHPの仕様としては初歩的な考え方で、ミスっていました。

 

以下のようにしてしまうと、Exceptionでcatch出来るのは、同じネームスペース内のExceptionのみになってしまいます。

Socialite::driver内でのExceptionはcatch出来ません。

 

 

Socialite::driver内のExceptionをcatchするには、以下のように、Exception ではなくて、バックスラッシュを付けてグローバルな名前空間であることを示して、\Exception をcatchする必要があります。

 

 

これでOKです。

 

まとめ

Exceptionのグローバルなnamespaceの考え方は、C#にもJavaにも存在しない概念のはずです。

私のようにJava、C#出身のPHPプログラマーは勘違いしてしまいます。

 

PHPの文法は以下の本で勉強し直します。

PHPとデータベース連携を学べる中級以上向けの本、おすすめ
PHPを学習していて基本的な文法をマスターした後にデータベース連携やユーザー認証、CRUD処理などをするのに適した本を探していて次の本を見つけました。 この種はWEBサイトよりもまとまった本が重宝します。 いずれもPHPのいわゆるフレーム...

 

どれか一冊という人には以下の「PHP+MySQLマスターブック」をおすすめします。

最後まで読んでいただきありがとうござました。
この記事が気に入っていただけたらシェアしてくれると嬉しいです。

 

コメント