Ни для кого не секрет, что Zend_OpenID не всегда работает так, как хотелось бы.
Сегодня я столкнулся с тем, что этот компонент не принимал ответ от openID-сервера google, выдавая ошибку “Discovery failed”. После изучения исходных кодов я выяснил, что необходимый для корректной валидации код просто отсутствует в компоненте. Пришлось воспользоваться грязным хаком (источник):
-
В метод Zend_OpenId_Consumer::_discovery(), в серию условий if preg_match (начало около строки 740), надо добавить следующий блок:
1
2
3 -
Класс тот же, метод _checkId(). В блок if ($version <= 2.0), в if ($this->_session !== null) надо добавить:
1
2
3
4if ($server == 'https://www.google.com/accounts/o8/ud') {
$this->_session->identity = 'http://specs.openid.net/auth/2.0/identifier_select';
$this->_session->claimed_id = 'http://specs.openid.net/auth/2.0/identifier_select';
} -
Там же, следующая ветка – else if (defined(‘SID’)):
1
2
3
4if ($server == 'https://www.google.com/accounts/o8/ud') {
$_SESSION['zend_openid']['identity'] = 'http://specs.openid.net/auth/2.0/identifier_select';
$_SESSION['zend_openid']['claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select';
} -
Там же, вне if/else if/else ветки, но внутри $version <= 2.0:
1
2
3
4if ($server == 'https://www.google.com/accounts/o8/ud') {
$params['openid.identity'] = 'http://specs.openid.net/auth/2.0/identifier_select';
$params['openid.claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select';
}
Конечно, это некрасивое решение, но оно приемлемо до тех пор, пока этот баг не будет закрыт.