[Из песочницы] Особенности работы с API Google Drive

Недавно нам нужно было сделать простое приложение для Google Drive. Приложение должно было формировать список пользователей, на которых расшарены документы в указанной папке с возможностью редактирования. Задача, в принципе, простая, поэтому недолго думая развернул болванку проекта на angularJS и начал кодить. Гугл, подумал я, это же большая компания, у него должен быть понятный и стабильный API и я сделаю это за пару дней.Я был слишком наивен.

АвторизацияПриложение подразумевало отсутствие серверной части (только клиентский js), поэтому для авторизации и идентификации было решено использовать авторизацию гугла. Авторизация — это же просто! Но не тут-то было. Для идентификации пользователя между экранами приложения решил хранить объект авторизации, который возвращается методом gapi.auth.getToken (). Метод штатный, все как бы для этого и создано. Но при сериализации этого объекта постоянно возникала забавная ошибка «Permission denied to access property 'toJSON'». Ошибка «интуитивно» понятная, поэтому потратил на нее пол дня. Оказалось, что в объекте, который возвращает эта функция, есть циклическая ссылка на самого себя. Циклическая ссылка содержалась в переменной g-oauth-window. Поэтому простой код решил эту проблему: var oAuthObj = gapi.auth.getToken (); oAuthObj['g-oauth-window'] = null; $window.localStorage.setItem ('googlerSession', JSON.stringify (oAuthObj)); Следующая проблема при клиентской авторизации — это возобновление клиентской сессии. Сессия аутентификации при использовании только клиентской аутентификации сохраняется на 1 час. Но как возобновить ее или продлить — не понятно. Мои танцы с бубном с повторной авторизацией и прочим шаманством не смогли мне помочь, поэтому до сих пор клиентская часть у меня авторизует пользователя на 1 час. Для удобства вывел в верхнее меню время, оставшееся до инвалидации сессии. В принципе, для этого инструмента 1 часа вполне хватает.Работа с документами И тут не обошлось без проблем. Первая незадача, с которой столкнулся — как получить внешнюю ссылку на документ? Если с обычными документами все хорошо — она берется из свойства alternateLink объекта файла, то с папкой какая-то магия. Любая папка возвращается в виде ссылки на странный интерфейс folderview, который я до этого никогда не видел. Гугление ни к чему не привело, поэтому пришлось исправлять это некрасивым кодом: var fileLink = fileObject.alternateLink; if (fileLink.indexOf («folderview») != 0) { fileLink = fileLink.replace («folderview? id=»,»#folders/»); fileLink = fileLink.replace (»&usp=drivesdk»,»); fileLink = fileLink.replace («docs.google.com», «drive.google.com»); } Права на документы Весь массив владельцев документа я строил относительно userId, который отдает гугл. Я думал, он уникальный и дает полное понимание, что это один и тот же пользователь. Но это оказалось не так. Согласно документации drive.permissions.list, в качестве id возвращается идентификатор пользователя (пруфлинк). Но в реальности оказалось, что это не тот идентификатор, который я ищу. Почему так — для меня до сих пор остается загадкой. Поэтому для идентификации и «узнавания» пользователя в списке владельцев я использовал email. Но это еще пол беды.Такая путаница с идентификаторами приводит к другому забавному багу. Если текущий авторизованный пользователь является читателем документа, то permission.list не возвратит список прав доступа. Следовательно, что бы показать, что я читатель — я использую информацию из userInfo текущего пользователя. А если этот же человек потом будет в permission.list другого файла, например, владелец документа, то у него будет совсем другой идентификатор. Это приводит к тому, что в списке пользователей текущий авторизованный пользователь может быть продублирован.

93bd6bc1be894911a827fa9455f7e545.png

Вывод: идентификатору пользователя доверять нельзя, тк он может меняться. Для идентификации пользователя лучше использовать email, хотя, теоретически он может отсутствовать. Например, если документ расшарен на корпоративный домен, то в этом случае email не будет, так как он расшарен на всех пользователей, которые принадлежат этому домену.

Была еще пара мелочей, которые уже вылетели из головы. Например, в объекте с информацией о файле не было нескольких переменных описанных в документации. Честно говоря уже не помню каких, но это уже мелочи.

P.S. Что из этого всего получилось, можно наблюдать здесь (http://googler.chililab.pro). Если есть идеи, как дополнить сервис, пишите в комментариях — реализую.

P.P. S. Если вы знаете красивое решение описанных в статье проблем, напишите в личку или в комментариях. Думаю, я не первый, кто столкнулся с этими проблемами.

© Habrahabr.ru