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

contact us お問い合わせ

Contact お問い合わせ・ご相談

Webサービス・システム開発の
ご相談はお気軽にご連絡ください。

Recruit 求人へのご応募

サニージェムでは現在、プロジェクトの推進を
担う仲間を募集しています。