cakephp3 google authで自動ログイン導入
2021/07/01
まずgoogle cloud platformに登録して、https://qiita.com/kmtym1998/items/768212fe92dbaa384c27 を参考に
client_id, project_id, client_secret_idを取得。
gitignore指定でjsonファイルを作る。
config/google_client_secret.json
{
"web":
{
"client_id":"hogehoge_client_id.apps.googleusercontent.com",
"project_id":"hogehoge",
"auth_uri":"https://accounts.google.com/o/oauth2/auth",
"token_uri":"https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
"client_secret":"hogehoge_client_secret",
"redirect_uris":[
"https://your_service.com/logins/google_callback",
"https://www.your_service.com/logins/google_callback"
],
"javascript_origins":[
"https://your_service.com",
"https://www.your_service.com",
]
}
}
~
“redirect_uris”もgoogle側で指定しないとエラーになります。
コントローラー側で使うのは2つのメソッドです。ここからはほとんど公式のPHPサンプルをカスタマイズしているだけなので、フレームワークは関係ないです。cakephpでの書き方にするべきなのでしょうが素のPHPのままがある
LoginsController.php
public function googleLogin()
{
$client = new Google_Client();
//さっきのjsonをセット
$client->setAuthConfig(__DIR__ . '/../../config/google_client_secret.json');
//リダイレクト先もセット
$client->setRedirectUri('https://' . $_SERVER['HTTP_HOST'] . '/logins/google_callback' );
$client->addScope(['email', 'profile']);
$client->setAccessType('offline');
$client->setIncludeGrantedScopes(true);
$state = substr(base_convert(hash('sha256', uniqid()), 16, 36), 0, 40);
$this->_session->write( 'google.state_token', $state );
$client->setState($state);
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
exit();
}
public function googleCallback()
{
$client = new Google_Client();
$client->setAuthConfig(__DIR__ . '/../../config/google_client_secret.json');
$client->setRedirectUri('https://' . $_SERVER['HTTP_HOST'] . '/logins/google_callback' );
// 正常なリクエストではなかった場合の処理
if ( $this->request->getQuery('state') !== $this->_session->read('google.state_token') )
{
// Googleログインに失敗した場合は `/`にリダイレクトし、処理を終了させる
$redirect_uri = 'https://' . $_SERVER['HTTP_HOST'];
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
exit;
}
$code = $this->request->getQuery('code');
$client->authenticate($code);
$token = $client->getAccessToken();
$client->setAccessToken($token['access_token']);
$abjAuth = new Google_Service_Oauth2($client);
if ( $client->getAccessToken() !== null )
{
$user = $abjAuth->userinfo->get();
$this->Auth->setUser( $user );
$this->setAutoLogin( $user['id'] );
return $this->redirect([ 'controller' => 'Tops', 'action' => 'index' ]);
}
}
ざっくりとセッションにトークンを持たせて、グーグル側での発行したトークンと同じだったら、同じ人ねオッケー!って感じで認証が完了する
このままだと、既にアカウントがあったりするユーザーは退会してやり直さないといけないので、中でまた処理を追加する必要あり。
仕組みの勉強でこれがわかりやすかった https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be
公式 https://github.com/googleapis/google-api-php-client
公式 https://developers.google.com/identity/protocols/oauth2/web-server