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 サービスでアクセストークンの取得その2

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

#11 アクセストークンを取得しよう (2)
http://dotinstall.com/lessons/google_connect_php_v2/9911
を参考に
アクセストークン取得を実装

前回、パラメータを設定したので
curl を使うところから開始

curl_setopt($curl, CURLOPT_URL,$url);
これは決まり文句らしいけど
意味を検索

http://php.net/manual/ja/function.curl-setopt.php

curl_setopt() のリファレンスがあるので、これを参照

curl_setopt() は
curl 転送用オプションを指定する関数

引数の解説をメモすると

$curl
は、curl_init() がかえす curl ハンドル

CURLOPT_URL
は、取得するURLとなる
ttp
このほかにもいくつかオプションを設定する

curl_setopt($curl, CURLOPT_POST,1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

これらのオプションの解説メモ

curl_setopt($curl, CURLOPT_POST,1);
CURLOPT_POST

は、POSTを行う
POST は、
application/x-www-form-urlencoded 形式
なので、一般的なHTMLフォームとおなじ

curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params));
CURLOPT_POSTFIELDS

は、POSTで送信するすべてのデータを指定する

http_build_query() 

は、URLエンコードされたクエリ文字列を作成する関数
web api でよくある & で結合したURLをつくる
関数については
http://php.net/manual/ja/function.http-build-query.php
のリファレンスを参照

http_build_query($params)

なので $params で client_id などを設定したので
これらをパラメータとして
リクエストURLが作成される

curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

CURLOPT_RETURNTRANSFER


true を設定すると
curl_exec() の返り値を文字列でかえす
通常だとデータを直接出力する

これらのオプション設定ができたら

$rs = curl_exec($curl);

で実行する

curl_exec() については
http://php.のnet/manual/ja/function.curl-exec.php
のリファレンスを参照

この関数は、指定した curl セッションを実行する

curl の実行が終わったら

curl_close($curl);

で閉じるのを忘れずに

curl_close() は
curl セッションを閉じる
http://php.net/manual/ja/function.curl-close.php
のリファレンスも参考にする

返ってきた値の $rs は
JSON形式なので

$json = json_decode($rs);

でJSON文字をデコードして
PHPの変数に変換する

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

この
$json
には、アクセストークンが入っているので
それを確認するため、一度
var_dump() を使って
画面に表示する

var_dump($json); exit;

そのまま再度ブラウザをリロードしても
セッション関連でエラーになる ため
一度 index.phpからアクセスしなおす

これで、ブラウザで
アクセストークンが表示されていれば成功

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
に掲載されている

google サービスログイン画面作成

google サービスログイン画面作成

#06 ログイン画面を作ろう
http://dotinstall.com/lessons/google_connect_php_v2/9906
を参考に
ホーム画面でのログインチェック実装と
ログイン画面の作成

まずはログイン画面の確認

しかし、なにも表示されない
原因はいくつか考えられるけど
よくよく考えたら
vagrant 環境のほうには
mysql-devel をインストールしていなかった

しかも今回はremi レポジトリを使っているので
sudo yum install mysql-devel では
バージョンが古く、インストールでエラーがでる

このため

 sudo yum install -y --enablerepo=remi mysql-devel

でインストール

sudo vim  /etc/php.ini

でファイルを開いて
876行めに

extension=pdo.so
extension=pdo_mysql.so

を追記

変更を保存して

sudo service httpd restart

で apache 再起動

これでもダメなので確認してみたら
PDO

POD
になっていたり

h() の中で、return が書いていないなど
簡単なミスが多かった

わからなかったときの対処として
ドットインストールのようにソースがあるなら
コピペして新しいファイルをつくり
diff -w ソースのファイル コピペファイル
として
差分を表示すると
わかりやすくなる

これで、ようやく準備ができたのでログインチェック

これにはセッションを使うので

session_start();
を追記

ログイン判定には
if(empty($_SESSION['me'])){

で判定

これは、$_SESSION[‘me’]
の値が空なのかを
empty() で判定している

もし、空だったら
header() を使ってログインページに飛ばす

header('Location: '.SITE_URL.'login.php');
exit;

これで、ログイン画面にとばせるので
次にログイン画面になる
login.php を作成

ソースはHTMLがほとんどなので
cp base.html login.php でカスタマイズしたほうが楽

ここにはログインするリンクを作成する

<p>
<a href="redirect.php">Googleアカウントで Login</a></p>