Google OAuth + PHP でログイン処理の実装


Twitter、facebook に続いて、会員制サイト作るときに Google のアカウントでログインできるようにするアレです。激しく今更感がありますが、メモ用にまとめます。

  • PHP
  • json_decode 使うのでPHPのバージョンが古いと入ってないかも。
  • access_token 取得に pecl_http も必要です。file_get_contents(でPOST)、curl ではなぜか失敗してしまったのでやむを得ず

イメージ

必要なモジュールのインストール

CentOSの場合です。他ディストリビューションを使っている場合は適宜読み替えてください。
これ php から POSTして access_token 取ってくるためだけに必要なので、面倒くさい or 入れれない、って場合は javascript でも取ってこれます・・・。

# まだ入れてない場合
yum install php-devel php-pear httpd-devel pcre-devel

# json のインストール。php5.2以降なら不要なはず
pecl install json

# jsonを有効にするため php.ini に 追記(末尾とか適当に)
vi /etc/php.ini
extension=json.so

# pecl_http のインストール
yum install curl-devel
pecl install pecl_http

# pecl_http を有効にするため php.ini に 追記(末尾とか適当に)
vi /etc/php.ini
extension=http.so

アプリケーション登録してクライアントIDを取得

まずGoogle APIs consoleへ。「Create Project…」をクリック

次の画面で「Create an OAuth 2.0 client ID…」をクリック

Product name: アプリケーション名を入れます。
Product logo: アプリケーションのロゴを設定するとよさそう。今回テストなので何もUpしません。
「Next」をクリック

Application type: Web application を選択
Your site or hostname: 「http または https」を選択。アプリのURLを入力
「Create client ID」をクリック

無事作成されるとこんな画面になるので「Client ID」「Client secret」「Redirect URIs」をメモります。

Redirect URIs は変更できる

default のままだとRedirect URIs(Googleで認証した後に飛ばされるURL)が、アプリのURL/oauth2callback に設定されます。Twitter、facebookと異なりGoogleの場合は、ここで登録したURIと認証用の画面にアクセスする際に指定するURIが異なるとエラーになってしまいます。
defaultのままで都合が悪い場合は、↑の画像右側にある「Edit settings…」をクリックして Redirect URIs を変更しておきましょう。

login page を作る

図の一番上のログイン用ページを作ります。よくある作りならログインページが出る == session が切れてるはずなので、自前ログイン、Twitterアカウントからログイン、Facebookアカウントでログイン、Googleアカウントでログインみたいなページになると思います。

最低限、getCode.php へのリンクがあればOKです。

getCode.php を作る

getCode.php

<?php

define('CLIENT_ID', 'メモった Client ID');
define('CALLBACK', 'メモった Redirect URIs');

$baseURL = 'https://accounts.google.com/o/oauth2/auth?';
$scope = array(
	'https://www.googleapis.com/auth/userinfo.profile', // 基本情報(名前とか画像とか)
	'https://www.googleapis.com/auth/userinfo.email',   // メールアドレス
	);

// 認証用URL生成
$authURL = $baseURL . 'scope=' . urlencode(implode(' ', $scope)) .
	'&redirect_uri=' . urlencode(CALLBACK) .
	'&response_type=code' .
	'&client_id=' . CLIENT_ID;

// Redirect
header("Location: " . $authURL);

コードの説明

3〜4行目: メモったApp ID, App Secret を設定します。
5行目     : facebookから戻ってくるURLを設定。もちろん http or https から入れてください。
7〜8行目: facebook認証用のURLを生成
10行目   : 生成したURLへのRedirect

getCode.php へアクセスすると初回は、Google認証画面へ飛ばされて

認証済み+2回目以降ならGoogle認証画面から直接Redirectされて Redirect URIs に指定したURLへ飛ばされるようになります。

callback.php を作る

google認証画面からの遷移先、callback.php を作ります。
callback.php

<?php

define('CLIENT_ID', 'メモった Client ID');
define('CLIENT_SECRET', 'メモった Client Secret');
define('CALLBACK', 'メモった Redirect URIs');

$code = $_REQUEST['code'];

// access_token 取得
$baseURL = 'https://accounts.google.com/o/oauth2/token';
$params = array(
	'code'          => $code,
	'client_id'     => CLIENT_ID,
	'client_secret' => CLIENT_SECRET,
	'redirect_uri'  => CALLBACK,
	'grant_type'    => 'authorization_code'
);

$req = new HttpRequest($baseURL, HttpRequest::METH_POST);
$req->setPostFields($params);
$req->send();
$response = json_decode($req->getResponseBody());

if(isset($response->error)){
	// getCodeへ戻す
	echo 'エラー発生。<a href="getCode.php">最初からやりなおす</a>';
	exit;
}
$access_token = $response->access_token;

// ユーザ情報取得
$userInfo = json_decode(
	file_get_contents('https://www.googleapis.com/oauth2/v1/userinfo?'.
	'access_token=' . $access_token)
);

// google の id + name(表示名)をセット
$user_id = $userInfo->id;
$name    = $userInfo->name;

// 初回ユーザかチェックするロジック
if(){

	// 初回ユーザならDatabaseへの登録処理・・・などなど

}

// ログイン後の画面へ遷移

コードの説明

3〜5行目: メモったClient ID, Client Secret, Redirect URIs を設定します。

7行目: googleからRedirectされる際に code が渡されるのでセット
10〜21行目: 取得した code + Client ID + Client Secret + Redirect URIs から token 取得用のURLを生成

22行明: 取得したJson形式のResponseを json_decode します

24〜27行目: エラー処理。

28行目: access_token をセット

32〜35行目: access_token を使ってユーザ情報取得

42行目: facebook ID と自前アプリのデータベースなどを比較して初回ユーザかチェック。初回なら登録処理とか。

48行目: ログイン画面に遷移、とか

以上です。次はTwitter + facebook + Google まとめて認証できるようにしたソース公開予定。

Tag  

2 Responses to Google OAuth + PHP でログイン処理の実装

  1. 保育士転職 より:

    Definitely consider that that you stated. Your favourite
    justification seemed to be on the net the simplest factor to take into account of.

    I say to you, I definitely get irked whilst other
    people think about concerns that they just don’t recognise about.
    You managed to hit the nail upon the highest and defined
    out the entire thing with no need side effect , other people can take
    a signal. Will likely be back to get more. Thanks

  2. test より:

    This website truly has all of the information and facts I wanted
    concerning this subject and didn’t know who to ask.

コメントを残す

メールアドレスが公開されることはありません。

Top