Тема звучит прям как научный трактат :). Но, тем не менее, что есть — то есть. Буквально недавно получил письмо от одного из читателей блога. Полный текст письма, думаю, приводить не стоит, но смысл был в следующем — при успешной авторизации в аккаунте Google ни как не удается получить список всех контактов — сервер отвечает 401 ошибкой — «Неверный Token».
Все бы хорошо, но, дело в том, что у меня сейчас при работе над модулем GContacts.pas довольно часто используется компонент GoogleLogin и ни разу не было случая получения подобной ошибки.
Что делать? Попросил исходник программы, чтобы разобраться в чем там дело.
Вначале, обратимся к документации Google. Вот, что там сказано по поводу параметра service при использовании ClientLogin (аутентификация для настольных приложений):
Service — Имя службы Google, к которой вы запрашиваете доступ. Каждой из служб, использующих службу аутентификации, присвоено имя. Например, с Календарем Google связано имя «cl». Этот параметр необходим для доступа к службам, использующим API данных Google. В этом случае можно применять общее имя «xapi». Имена конкретных служб приведены в документации по этим службам.
Общее имя xapi. То есть получается, что xapi можно использовать при доступе к календарю и в случае, когда не известно, какую из служб Google мы будем использовать.
Проведем простую проверку и попробуем получить данные о контактах в Google. Приложение будет выглядеть элементарно:
Заносим в Edit’ы логин, пароль и адрес электронной почты в GMail и:
1. Проверяем результат аутентификации в службах Google
2. Пробуем получить количество контактов в адресной книге.
Для работы с Google подключаем в uses два модуля: GoogleLogin.pas и GContacts.pas. Теперь проверяем.
1. Аутентификация с использованием общего имени (service=xapi)
Листинг процедуры аутентификации и получения количества контактов:
procedure TForm3.Button1Click(Sender: TObject); var Login: TGoogleLogin; Contacts: TGoogleContact; begin Login:=TGoogleLogin.Create(Edit1.Text,Edit2.Text);//создаем объект Login.Login();//аутентификация в службах label5.Caption:=Login.LastResultText;//выводим результат Contacts:=TGoogleContact.Create(Login.Auth,Edit3.Text);//создаем объект для получения контактов label7.Caption:=IntToStr(Contacts.RetriveContacts);//считываем данные и выводим результат end;
Результат выполнения процедуры представлен на рисунке:
Заметьте — аутентификация пройдена успешно, получен ключ Auth для дальнейшей работы. А количество контактов равно нулю.
В ответе сервера приходит документ с ошибкой 401 «Invalid Token».
Теперь проверим работу с явным указанием сервиса к которому мы хотим получить доступ.
2.
1. Аутентификация с использованием имени сервиса (service=cp)
Листинг процедуры в этом случае практически не меняется:
procedure TForm3.Button1Click(Sender: TObject); var Login: TGoogleLogin; Contacts: TGoogleContact; begin Login:=TGoogleLogin.Create(Edit1.Text,Edit2.Text); Login.Service:=tsContacts;//явно указываем имя службы Login.Login(); label5.Caption:=Login.LastResultText; Contacts:=TGoogleContact.Create(Login.Auth,Edit3.Text); label7.Caption:=IntToStr(Contacts.RetriveContacts); end;
А результат, как и полагается, вернул все контакты из адресной книги:
Отсюда следует простой вывод: при аутентификации в службах Google всегда следует явно указывать ту службу, с которой вы хотите работать.
На всякий случай, ещё раз обращаю ваше внимание, что последняя версия компонента Delphi 2010 для аутентификации в службах Google доступна в нашем общем проекте здесь.
Отличный пример, только значение приведенной константы «tsContacts» не указано. В вышеупомянутых исходниках ее тоже нет. Исходя из таблички с сайта Goo: http://code.google.com/intl/ru-RU/apis/gdata/faq.html#clientlogin
становится понятно, что для Google Calendar (GCa) это «cl» а для Google Contacts это «cp». К сожалению и то и другое и «xapi» возвращают нуль… Кстати говоря, при успешном входе параметр Auth = », и вместо него я передаю заполненый SID. Может проблема как раз таки в этом? Кстати почему Auth может быть пустым?
Пустой Auth приходил только, когда использовал имя сервиса xapi. Других случаев просто не припомню…может имя пользователя не то, например, вместо мыла указан ник или ещё чего? SID использовать для авторизации никак нельзя, т.к. этот параметр зарезервирован для будущих нужд Google и пока к аутентификации отношения никакого не имеет.
Решил лучше несколько раз все перепроверить, подебагить код, посмотреть куда что передается, даже перекачал последние исходники GoogleLogin, и тем не менее, на данный код: Account := TGoogleLogin.Create(Edit1.Text, Edit2.Text); Account.Service := ‘cp’; Account.Login(); ShowMessage(Account.LastResultText); ShowMessage(Account.Auth); сначала приходит, при заполнении соответственно в форме своего логина и пароля, и нажатия на кнопку сообщение: ————————— google ————————— Аутентификация прошла успешно ————————— OK ————————— а затем, когда вывожу Auth, то ни чего не приходит, как говорится «а в ответ тишина» :) : ————————— google ————————— ————————— OK ————————— Ну уже который день не могу понять в чем дело.… Подробнее »
Сорри, за вышеуказанный коммент, стало стыдно, за то что не сразу врубился в найденый баг))) В общем трабла вот в чем: в строке с проверкой на вхождение Auth, написано следующее:
if pos(‘Auth’,UpperCase(List[i]))>0 then
соответственно когда идет преобразование ко всем заглавным буквам, но строку ‘Auth’ надо так же преобразовать к заглавию, т.е. ‘AUTH’.
Николай, я даже прочитать не успел, а вы уже сами ответили =)