google web サービスログアウト処理実装

google web サービスログアウト処理実装

#16 ログアウト処理を実装しよう
http://dotinstall.com/lessons/google_connect_php_v2/9916
を参考に、ログアウト処理を実装していく

編集するのは
index.php

まず、ログアウトするためのリンクを作成

<p><a href="logout.php">ログアウト</a></p>

そして、 vim logout.php
でファイルを作成し内容を書いていく

まず、設定ファイル関連を読み込む

require_once('config.php');
require_once('functions.php');

session_start();

セッションの内容を空にしたいので

$_SESSION = array();

とする

cookie も削除するので

if(isset($_COOKIE[session_name()])){

}

で cookie があるか判定し
あるなら削除する処理をしていく

cookie 削除処理は

setcookie(session_name(),'',time()-86400,'/google_connect_php/');

time()-86400 とすることで
範囲は1日前にしておく

次に、サーバー側のセッション情報を
破棄したいので

session_destroy();

ここまでできたら、index.php に戻りたいので

header('Location: '.SITE_URL);

とする

これで、google アカウントをつかってログイン
ログアウトする仕組みができる

全体の復習には
http://dotinstall.com/lessons/google_connect_php_v2
を参照

google web サービスログイン処理実装

google web サービスログイン処理実装

#15 ログイン処理を実装しよう
http://dotinstall.com/lessons/google_connect_php_v2/9915
を参考に
ログイン画面を実装して、ホーム画面にユーザ情報を表示

編集するファイルは redirect.php

まずは、ログイン処理
if(!empty($user)){
}
という判定で $user の中身が空でないか判定する
その後、セッションハイジャック対策をおこなうため
session_regerate_id()
を使って

session_regenerate_id(true);

とする

この session_regenerate_id() については
http://php.net/manual/ja/function.session-regenerate-id.php
のリファレンスを参考にする
この関数をつかうと
現在のセッションIDを新しく生成したものと置き換えることができる
ちなみに、現在のセッション情報は遺児されたまま

肝心のログイン処理だけど
これは
meという変数へ $user の値を入れればOK

$_SESSION['me'] = $user;

ここまでできたら
header() でホーム画面に飛ばす

header('Location: '.SITE_URL);

ここまでできたら、次に index.php を編集していく

body 要素のところへ

<p>
<?php echo h($_SESSION['me']['google_name']); ?>
(<?php echo h($_SESSION['me']['google_email']); ?>) のGoogleアカウントでログインしています</p>

と追記する

ここまでできたら、再び index.php へブラウザでアクセスして
google 認証すると
ログイン画面にて
アカウントの名前やメールアドレスが表示される

途中、ログイン画面でなにもでなくてこまったけど
vim index.php_base
でコピペして
自分のファイル
index.php と

diff -w index.php index.php_base
で違いを表示したら
h() のところがスペルミスしていた

google web サービスで」格納した情報の抽出

google web サービスで」格納した情報の抽出

#14 ユーザー情報を格納しよう (2)
http://dotinstall.com/lessons/google_connect_php_v2/9914
を参考に
DBへ格納したデータを抽出する

DBへ格納したデータを
$user へ入れていく

まず、レコードのIDを知りたいので

$myId = $dbh->lastInsertId();

で取得する

lastInsertId() については
http://php.net/manual/ja/pdo.lastinsertid.php
のリファレンスを参考にする

このlastInsertId() は
最後に挿入された行のID、あるいはシーケンスの値を取得する

これを使って $myId へその値を格納している

そして sql を実行していく

$sql = "select * from  users where id = :id limit 1";
$stmt = $dbh->prepare($sql);

$stmt->execute(array(":id"=>$myId));
$user = $stmt->fetch();

これで、格納できているか確認するため
var_dump() で中身をみてみる

var_dump($user);exit;

確認してみたら、
アクセストークンが違っていて
$me->access_token
ではなく
$json->access_token
だった

DBに追加した情報を削除したいので

mysql -u root -p
でログインして

delete from users;

でDBの内容を削除

再度、index.php から認証してDBに追加

追加できたら

select * from users;

でDBの中身を確認して
アクセストークンも含まれているなら成功

google web サービスで取得した情報をDB格納

google web サービスで取得した情報をDB格納

#13 ユーザー情報を格納しよう (1)
http://dotinstall.com/lessons/google_connect_php_v2/9913
を参考に
取得したユーザ情報をDBへ格納


$sql "insert into users(
	google_user_id, 
	google_email,
	google_name,
	google_picture,
	google_access_token,
	created,
	modified)
 values(

	:google_user_id, 
	:google_email,
	:google_name,
	:google_picture,
	:google_access_token,
	now(),
	now())";

とする

:google_user_id というように
: がついているのは
prepare() を使うから

この変数に格納された SQL を実行するので

$stmt=$dbh->prepare($sql);

パラメータを指定するので

$params = array(
	":google_user_id"=>$me->id. 
	":google_email"=>$me->email,
	":google_name"=$me->name,
	":google_picture"=>$me->picture,
	":google_access_token"=>$me->access_token);

これでパラメータがセットできたので実行

$stmt->execute($params);

google web サービスでユーザ情報の取得

google web サービスでユーザ情報の取得

#12 ユーザー情報を取得しよう
http://dotinstall.com/lessons/google_connect_php_v2/9912
を参考に
アクセストークンをつかってユーザ情報を取得

これについては
https://developers.google.com/accounts/docs/OAuth2WebServer?hl=ja#callinganapi

Calling a Google API
の部分を参考にする

これによれば
GETで
https://www.googleapis.com/oauth2/v1/userinfo?access_token=
にアクセスすることになる

このURL後ろにアクセストークンをつける

$url = 'https://www.googleapis.com/oauth2/v1/userinfo?access_token='.$json->access_token;

でURLを $url へ格納する

$json に access_token の項目が格納されているので

$json->access_token

としている

このようなAPIの引っ張り方は、他のweb api
で使うので
覚えておくと便利

これにアクセスして情報を得たいので

file_get_contents($url)

としている

file_get_contents() は
ファイルの内容をすべて文字列に読み込む関数
http://php.net/manual/ja/function.file-get-contents.php
のリファレンスを参考にするとわかりやすい

今回は $url で データを読み込むファイルを指定している
リファレンスだと filename に該当する部分

しかし、返ってくる値は json なので
json_decode() をつかってデコードする必要がある

json_decode() については
http://php.net/manual/ja/function.json-decode.php
のリファレンスを参考にする

今回は

json_decode(file_get_contents($url));

となる

このJSONデコードされたユーザ情報を変数に格納するので

$me = json_decode(file_get_contents($url));

とする

中身を確認したいので
var_dump() を使って確認

var_dump($me);

ただし、セッションの関係もあり、そのままリロードするとうまくいかないため
一度 index.php に戻って
再度 google の認証してから試すようにする

そのままだと見にくいので
右クリックして
ページのソースを表示とすれば
改行されてみやすくなる

情報取得が確認できたら
var_dump()
はコメントアウトして

DBへ情報を格納していく

$dbh = connectDb();

次に、SQLでユーザの存在を調べ
いないのならDBへ追加する

$sql ="select * from users where google_user_id = id limit 1";

このSQLを実行するため

$stmt = $dbh=>prepare($sql);
$stmt=>execute(array(":id"=>$me->id));
$user = $stmt=>fetch();

if でユーザの存在がなかったときにDB追加する判定は

if(!$user){
}

となる

google web サービスでアクセストークンの取得

google web サービスでアクセストークンの取得

#10 アクセストークンを取得しよう (1)
http://dotinstall.com/lessons/google_connect_php_v2/9910
を参考に
認証したユーザのアクセストークン取得処理を実装

アクセストークンの取得は
Handling the Response
をやっていく

リファレンスは
https://developers.google.com/accounts/docs/OAuth2WebServer?hl=ja#handlingtheresponse
を参考

code
client_id
client_secret
redirect_uri
grant_type
などのオプションをつかって

accounts.google.comのサイトの
/o/oauth2/token
へPOSTで投げかける

POSTで行うには
curl を使う

まず、パラメータを array() で作成する

$params = array(
	'client_id'=>CLIENT_ID,
	'client_secret'=>CLIENT_SECRET,
	'code'=>$_GET['code'],
	'redirect_url'=>SITE_URL.'redirect.php',
	'grant_type'=>'authorization_code'
);

とする

大文字の部分は、config.php で設定した定数

次に、アクセスするURLを変数へ格納

$url ='https://accounts.google.com/o/oauth2/token';

次に、curl を使っていくので
curl_init()

curl セッションを初期化し
新しい curl リソースを作成する

$url = curl_init();

curl_init() については
http://php.net/manual/ja/function.curl-init.php
を参照

googl 側でユーザ認証してもらう処理

googl 側でユーザ認証してもらう処理

#09 Googleで認証をしてみよう
http://dotinstall.com/lessons/google_connect_php_v2/9909
を参考に
Google側でユーザーを認証してもらうための処理を実装

まずは
scope の設定

scope は
スペースで区切って指定した情報をとってくる

動画で表示されている
Scopes for User Profile Permission がみあたらないので検索してみた

https://developers.google.com/accounts/docs/OAuth2LoginV1#formingtheurl

に掲載されている

ただ
Important: Google was an early adopter of OAuth 2.0 and created an early capability to perform authentication via OAuth 2.0. This document describes that initial implementation. Since creating this service, the OpenID Foundation has produced the OpenID Connect specification as a general way to authenticate users across identity providers using OAuth 2.0. Please see our updated OAuth 2.0 implementation which conforms to the OpenID Connect specification.
というメッセージがページ冒頭にもでているので
すでにバージョンが古いのかもしれない

とりあえず、これで進めてみる

https://www.googleapis.com/auth/userinfo.profile
でユーザのプロフィール取得

https://www.googleapis.com/auth/userinfo.email
でユーザのEメールを取得

scope を複数指定するには
スペース区切りでOKなので

'scope'=>
https://www.googleapis.com/auth/userinfo.profile 
https://www.googleapis.com/auth/userinfo.email';

とする

google にとばすには

$url ='https://accounts.google.com/o/oauth2/auth'

にパラメータをつけるので
web api でよく使うように
ベースURLになる
https://accounts.google.com/o/oauth2/auth
に?をつけてその後にパラメータをつけていく

このときに使っている便利な関数が
http_build_query()
これは
http://php.net/manual/ja/function.http-build-query.php
の解説にあるように
エンコードされたクエリ文字列を生成できる
というもの

今回は

http_buid_query($params)

としたので

$params = array(
'client_id'=>CLIENT_ID,
'redirect_url'=>SITE_URL.'redirect.php',
以下略
);

で指定した様々なパラメータが
client_id=CLIENT_ID&redirect_url=SITE_URL.’redirect.php’&
というような web api でよく見る
&でつなげたパラメータに変換される

これで

$url ='https://accounts.google.com/o/oauth2/auth?'.http_build_query($params);


$url へ google にとばすURLが格納されるので
header() で実際に飛ばす

header('Location: '.$url);
exit;

とする

次に、CSRF対策をしておく

if($_SESSION['state'] != $_GET['state']){
	echo '不正な処理です’;
	exit;
}

とすることで
state の値を検証して値が違うなら
エラーを表示して強制終了する

ここまでできたら、実働実験
仮想マシンをたちあげた状態で
http://dev.dotinstall.com/google_connect_php/

(ちなみに、ドメインは hostsファイルを 変更しているので、
このドメインでもローカルマシンにできる
自作やレンタルのサーバ
なら、自ドメインに変更する)

にアクセスして
Googleアカウントでログイン

クリックすると
Google の認証画面になり

アカウントの基本情報の表示
メール アドレスの表示

の許可をリクエストするので
承認する
をクリック

すると、画面は真っ白だけど
URLに
state

code
が返ってきているのがわかる

google webサービスでアクセストークンの取得

google webサービスでアクセストークンの取得

#10 アクセストークンを取得しよう (1)
http://dotinstall.com/lessons/google_connect_php_v2/9910
を参考に
認証したユーザのアクセストークンを取得するための処理を実装

アクセストークンを取得するには
Handling the Response
を使う

https://developers.google.com/accounts/docs/OAuth2WebServer?hl=ja#handlingtheresponse
のリファレンスも参照

google サービス認証ダイアログ作成

google サービス認証ダイアログ作成

#08 認証ダイアログを作ろう
http://dotinstall.com/lessons/google_connect_php_v2/9908
を参考に
CSRF対策実装
承認
を行う際の認証ダイアログの作成

認証ダイアログの作成は
https://accounts.google.com/o/oauth2/auth
にむけて
いろいろなオプションをつけて作成する

オプションに関しては
https://developers.google.com/accounts/docs/OAuth2WebServer?hl=ja#formingtheurl
のリファレンスを参考に

認証ダイアログ作成の前にCSRFを行う

これは
セッションのstate に推測しにくい文字列を入れ
googleにとばすときのURLにも
組み込んでおき
認証から返ってきたときの処理で
この値が正しいかチェックをするというもの
これにより
認証後にちゃんとgoogle から返ってきたことを確認できる

$_SESSION['state'] = sha1(uniqid(mt_rand(),true));

で、ハッシュにより値を作成
sha1() でハッシュを生成している
ハッシュについては
http://php.net/manual/ja/function.sha1.php
を参照

uniqid(mt_rand()

でランダムな値を生成して

オプションで true 指定なので
20 バイト長のバイナリ形式で返ってくる

値はできたので、次に認証ダイアログの
パラメータを作成

$params = array(
	'client_id'=>CLIENT_ID,
	'redirect_uri'=>SITE_URL.'redirect.php',
	'status'=>$_SESSION['state'],
	'approval_prompt'=>'force'.
	'scope'=>'',
	'response_type'='code',
);

クライアントIDは

'client_id'=>CLIENT_ID

リダイレクトURIは

'redirect_uri'=>SITE_URL.'redirect.php'

認証の値となる state は

'status'=>$_SESSION['state']

毎回認証ダイアログをひらくオプションとして

'approval_prompt'=>'force'

どのデータを引っ張ってくるか指定するのは

'scope'=>''

の部分で指定

レスポンスのタイプを

'response_type'='code'

とする

google サービス認証処理作成

google サービス認証処理作成

#07 認証処理の流れを確認しよう
http://dotinstall.com/lessons/google_connect_php_v2/9907
を参考に
redirect.php を作成し認証処理を実装

まず設定ファイルを読み込むため

require_once('config.php');
require_once('functions.php');

で読み込む

セッションを使うため

session_start();

も追記

処理としてはまず google にリダイレクトして
返ってきたら
ユーザ情報をゲットしていろいろと行う
という流れ

google に認証して GETで code がなければ
認証前ということになるので

if(empty($_GET['code'])){

と判別

この条件式が真なら、認証前になる

まず、認証前の場合
認証ダイアログを作成

認証のためのURLができるので
これで google にとばす

google にとばすと GETつきのダイアログになるので
ここから先は認証後の処理になる

認証後の処理は
アクセストークンを取得し
ユーザ情報を取得する

このユーザ情報をDBに格納して
ログイン処理

これらが終了したら
ホーム画面の index.php にとばす
という流れ

この詳しい流れについては
https://developers.google.com/accounts/docs/OAuth2WebServer?hl=ja
に掲載されている