2010-07-28 3 views
30

Я создаю веб-сервис и хотел бы использовать учетные данные учетной записи пользователя google.Учетные данные Webservice - OpenID/Android AccountManager?

Служба работает на GAE и будет иметь веб-клиент и собственный клиент Android.

Это моя первая попытка что-то вроде этого, и я читал об OpenID и библиотеке AccountManager Android.

Я все еще не уверен, какие у меня варианты с точки зрения хранения пользователей в моем хранилище данных. Какой идентификатор я должен использовать? Можно ли использовать OpenID в приложении для Android?

Любая помощь и/или указатели будут оценены. Благодарю.

ответ

30

У нас были аналогичные требования последнего проекта: GAE бэкенд с GWT фронтэнда и Android/iPhone. Кроме того, мы не хотели хранить учетные данные пользователя.

Итак, мы решили использовать OpenID, который, к сожалению, является веб-стандартом и не очень хорошо работает с мобильными устройствами, но выполним.

На стороне GAE мы просто включили федеративный логин, который дал нам OpenID.

На мобильных устройствах, когда пользователю необходимо войти в систему, мы представляем им список оппонентов OpenID (Google, Yahoo и т. Д.). Затем мы открываем собственный браузер (не встроенный браузер) и напрямую на выбранный сайт аутентификации OpenID. Поверхность заключается в том, что браузер пользователя обычно уже имеет имя пользователя/пароль, поэтому этот шаг требует, чтобы пользователь нажал одну кнопку.

Все это довольно просто. Теперь вот сложная часть: После того, как пользователь подтвердит вход в систему, OpenID перенаправляет обратно на наш возвратный url GAE (вам нужно указать этот URL-адрес, когда запрос сделан). На этот адрес мы создаем пользовательский URL, например:

yourappname://usrname#XXXYYYZZZ 

где XXXYYYZZZZ является маркер аутентификации. Мы получаем этот токен с страницы возврата, где он хранится в виде файла cookie ACSID: мы использовали некоторый JSP, чтобы прочитать этот куки-файл и перенести его поверх пользовательского URL-адреса.

Затем мы регистрируем наши приложения для Android и iPhone для обработки URL-адресов yourappname://, так что, когда пользователь cliskc этой ссылки, наше приложение вызывается и ссылка передается на него. Мы извлекаем имя пользователя и токен из этой ссылки, и мы используем его в запросах REST для бэкэнда GAE.

Если у вас есть еще вопросы, я бы с радостью обновил это сообщение.

Update:

Куки сеанса пользователя по производству AppEngine назван ACSID, в то время как на развитие AppEngine сервера он называется dev_appserver_login.

+0

+1 - очень подробно! Что показывает текст пользовательского URL? «Нажмите, чтобы вернуться в приложение»? Или что-то типа того? –

+0

Он может показывать все, что вам нравится. Я использовал ссылку «Продолжить ..», которая выглядит как кнопка. С помощью некоторого javascript вы можете запустить приложение автоматически, не требуя от пользователя щелчка по ссылке - не пробовал это, его нужно было бы протестировать. –

0

http://developer.android.com/search.html#q=AccountManager&t=0

http://developer.android.com/resources/samples/SampleSyncAdapter/index.html в нижней части этой страницы вы найдете все необходимое код

наилучшими пожеланиями

+0

Связанный пример не использует OpenID или Xauth, поэтому его нельзя использовать для GAE для аутентификации против существующих учетных записей Google. Как я вижу, он использует собственную схему аутентификации: простой POST с именем пользователя/паролем в качестве параметров заголовка. –

+0

, хотя у @peterKnego есть точка относительно второй рекомендации, первая ссылка на самом деле весьма полезна. но я согласен с тем, что больше внимания следует уделить формулированию правильного ответа, fmo. но будьте осторожны, чтобы не быть опущенным в будущем. –

12

Я потратил около недели, чтобы найти подходящий и современный способ для этого - без веб-браузера и с помощью диспетчера аккаунта Android.

Если вы хотели бы использовать учетную запись Google и AccountManager для идентификации пользователя, вы можете:

  1. Получить свой маркер Google Contacts (Auth типа лексемы «ф») через AccountManager на фоне резьбы :

    public String getUserToken(Activity activity) 
    { 
        AccountManager accountManager = AccountManager.get(activity); 
        AccountManagerFuture<Bundle> amf = accountManager.getAuthTokenByFeatures("com.google", "cp", null, activity, Bundle.EMPTY, Bundle.EMPTY, null, null); 
    
        Bundle bundle = null; 
        try { 
         bundle = amf.getResult(); 
         String name = (String) bundle.get(AccountManager.KEY_ACCOUNT_NAME); 
         String type = (String) bundle.get(AccountManager.KEY_ACCOUNT_TYPE); 
         String token = bundle.getString(AccountManager.KEY_AUTHTOKEN); 
         return token; 
        } catch (OperationCanceledException e) { 
         e.printStackTrace(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } catch (AuthenticatorException e) { 
         e.printStackTrace(); 
        } 
        return null; 
    } 
    
  2. Pass получил UserToken к серверу через обеспеченного канала.

  3. Validate маркер на сервере с помощью Google, используя GData библиотеку (Google Data API library):

    public String getUserId(String token) 
    { 
        ContactsService contactsService = new ContactsService("Taxi"); 
        contactsService.setUserToken(token); 
    
        IFeed feed = null; 
        try { 
         feed = contactsService.getFeed(new URL("https://www.google.com/m8/feeds/contacts/default/full?max-results=10000"), ContactFeed.class); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } catch (ServiceException e) { 
         e.printStackTrace(); 
        } catch (NullPointerException e) { 
         e.printStackTrace(); 
        } 
    
        if (feed == null) 
         return null; 
    
        String externalId = feed.getId(); 
        IPerson person = feed.getAuthors().get(0); 
        String email = person.getEmail(); 
        String name = person.getName(); 
        String nameLang = person.getNameLang(); 
    
        return externalId; 
    } 
    
  4. маркер Google может истекать (обычно через час), так что если вы не в состоянии проверить маркер на сервере , вы должны отправить ответ клиенту, аннулировать токен и получить новый. Используйте менеджер счета недействительным маркер:

    public void invalidateUserToken(Context context, String token) 
    { 
        AccountManager accountManager = AccountManager.get(context); 
        accountManager.invalidateAuthToken("com.google", token); 
    } 
    
+0

Можно ли сделать то же самое (получить токен, который будет использоваться) для сообщений электронной почты в gmail и для facebook? если да, можете ли вы ответить на него в следующем посте: http://stackoverflow.com/questions/11532257/use-syncadapter-to-sync-with-local-gmail-and-facebook-app-data –

+0

Но это не так. «Решить проблему, так как он хочет аутентифицировать пользователя на своем собственном веб-сервисе с помощью базы данных, я думаю, поэтому, если он хочет аутентифицироваться в своем веб-сервисе, он должен отправить токен и его идентификатор Google в веб-службу, а веб-служба должна отправить токен на сервере Google, который отправляет ответ с идентификатором Google, который вы можете сравнить с идентификатором Google, который пользователь отправил, не так ли? Как ты это делаешь ? – Karly

+1

Я протестировал это решение, и он отлично работает, если вам просто нужен аутентифицированный адрес электронной почты от вашего пользователя. Потенциал заключается в том, что вы можете делать все в своем приложении без веб-браузера. Недостатком является то, что вы должны попросить разрешения на редактирование контактов пользователя, которые некоторые могут не решаться. Кто-нибудь знает, как можно просто запросить аутентификацию без запроса _authorization_? – thomas88wp

3

Я думаю this блог делает именно то, что вы хотите. Это сработало для меня. Оба решения, размещенные здесь, являются жизнеспособными и умными, но я думаю, что это делает именно то, о чем спрашивал ассер.

По существу, вы просто получаете authToken, используя область «ah», и передаете ее на нужную веб-страницу, чтобы получить файл cookie ACSID, который позволит вам получить доступ к любой странице AppEngine, использующей UserService для аутентификации.

Смежные вопросы