Opauth und Google OpenID 2.0

Google stellt im April 2015 den Support von OpenID 2.0 ein. Man kann nun auf Google Sign-In oder Google OpenID Connect umstellen. Ansich kein Problem, anhand von Bibliotheken wie Opauth schnell umsetzbar. Allerdings werden OldStyle-OpenIDs im Format https://www.google.com/accounts/o8/id?id={xyz] dabei nicht mehr zurückgegeben. Wer seine User bisher anhand dieser OpenIDs identifiziert hat, steht vor einem Problem, denn sie sind inkompatibel zu den neuen Google-UserIds. Für die PHP-Bibliothek Opauth gibt es eine relativ elegante Lösung.

Folgt man den Schritten in der Google-Anleitung Migrating from OpenID 2.0 to OpenID Connect und nutzt die Opauth-Library, so sind folgende Anpassungen nötig:

  1. openid.realm in der opauth.conf.php einbauen:

    Fettschrift = neu einfügen
      
        'Strategy' => array(
            'Google' => array(
                'client_id' => 'xxx',
                'client_secret' => 'xxx',
                'openid.realm' => 'http://www.mydomain.url',
            ),
    [...]
  2. $optionals und $scope in der GoogleStrategy.php erweitern:
    public $optionals = array('redirect_uri', 'scope', 'state', 'access_type', 'approval_prompt', 'openid.realm', );
    public $defaults = array(
        'redirect_uri' => '{complete_url_to_strategy}oauth2callback',
        'scope' => 'openid profile email'
    );
  3. Include eines JWT-Decoders, z.B. PHP-JWT in der index.php von Opauth, z.B. include("lib/php-jwt-master/Authentication/JWT.php");
  4. Anpassung der GoogleStrategy.php (lib/opauth/Strategy/Google/GoogleStrategy.php) - Methode oauth2callback():

    Fettschrift = neu einfügen   

    $url = 'https://accounts.google.com/o/oauth2/token';
                $params = array(
                    'code' => $code,
                    'client_id' => $this->strategy['client_id'],
                    'client_secret' => $this->strategy['client_secret'],
                    'redirect_uri' => $this->strategy['redirect_uri'],
                    'grant_type' => 'authorization_code'
                );
                $response = $this->serverPost($url, $params, null, $headers);
               
           
                $results = json_decode($response);

                // Unterstützung bis Januar 2017
                if (date("Y")<2017) {
                    $results->id_token=JWT::decode($results->id_token, null, array('RS256'));
                }

                if (!empty($results) && !empty($results->access_token)){
                    $userinfo = $this->userinfo($results->access_token,$code);
                   
                    $this->auth = array(
                        'provider' => 'Google',
                        'uid' => $userinfo->id,
                        'info' => array(
                            'name' => $userinfo->name,
                            'email' => $userinfo->email,
                            'first_name' => $userinfo->given_name,
                            'last_name' => $userinfo->family_name,
                            'image' => $userinfo->picture
                        ),
                        'credentials' => array(
                            'token' => $results->access_token,
                            'expires' => date('c', time() + $results->expires_in)
                        ),
                        'raw' => $userinfo,
                        'openid' => $results->id_token
                    );
    [...]

Fertig. Das Resultat nach einem erfolgreichen Google-Login enthält nun die veralteten Google-OpenID-2.0-Daten und die neuen Google OpenID-Connect-Daten. Letztere sollte man unbedingt speichern, da die alten OpenIDs ab 2017 nicht mehr abrufbar sind-

code:wendt