Во второй части этого урока мы рассмотрим процесс входа в Google и получения уникального идентификатора. Мы попытаемся написать общий код, который позже сможем использовать для процесса входа в Facebook. Но сначала давайте рассмотрим, что на самом деле означает «вход в систему»…
Когда вы обрабатываете свой собственный список пользователей и пользователь регистрируется в процессе регистрации, вы обычно можете спросить этого пользователя о чем угодно. Тем не менее, когда пользователь входит в систему через Facebook, Google или любую другую службу, вы получаете доступ к этой службе для получения сведений о пользователе … Это до боли понятно с такими службами, которые по умолчанию не предоставляют даже адрес электронной почты при входе в систему. Иногда он доступен в Facebook, но только для пользователей, которые не хотят его скрывать.
Хуже того, одной из основных причин использования такого сервиса является доступ к контактам … Однако Facebook больше не позволяет разработчикам получать доступ к вашим друзьям на Facebook. Разработчик приложения Facebook может получить доступ только к списку друзей, у которых установлено приложение, и для этого нам нужно будет «пригласить» людей использовать / установить приложение.
Начало работы — Конфигурация
Почти все, что обсуждается в этом блоге, освещено здесь . Тем не менее, это довольно общий пост, поэтому в этом уроке я постараюсь быть более конкретным.
Начните с перехода на консоль разработчика Google: https://console.developers.google.com/
Создайте новое приложение, нажав кнопку «Создать»:
Просто введите название приложения, например, в этом случае его SocialChat и нажмите «Создать»:
Теперь можно выбрать раздел API, где вы должны увидеть страницу нового проекта:
В этом проекте вы должны нажать Google+ API в разделе «Социальные сети»:
В разделе учетных данных создайте новый идентификатор клиента, сначала нам нужно создать его для веб-приложения. Это будет использоваться симулятором, чтобы мы могли отлаживать приложение на рабочем столе. Он также будет использоваться портами для JavaScript, рабочего стола и эффективно для всего, кроме iOS и Android:
Экран концентрации используется, чтобы запрашивать у пользователей разрешения, обычно вы должны правильно его заполнять для приложения «реального мира», но в этом случае мы оставили его в основном пустым для простоты:
Теперь нам нужно добавить привязки нативных приложений для Android / iOS практически так же, как мы делали веб-приложение:
Чтобы создать собственное приложение для Android, убедитесь, что вы правильно настроили хранилище ключей для своего приложения. Если у вас нет сертификата Android, вы можете воспользоваться нашим визуальным мастером или использовать командную строку, указанную в нашем руководстве по подписыванию .
Теперь, когда у вас есть сертификат, вам нужно два значения для вашего приложения, первое — это имя пакета, которое должно совпадать с именем пакета вашего основного класса (с методами start, stop). Он должен быть указан в разделе свойств Codename One. Убедитесь, что вы используете абсолютно уникальное имя и используете свой собственный домен, не используйте префикс com.codename1 или что-нибудь подобное …
Вам также нужно значение SHA1 для вашего сертификата, это объясняется Google здесь: https://developers.google.com/+/mobile/android/getting-started
Эффективно вам нужно запустить эту командную строку:
|
1
|
$ keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v |
Это запросит пароль, а затем напечатает несколько строк данных, одна из которых должна начинаться с SHA1 то есть значения, которое вам понадобится для приложения Android.
Приложение iOS должно иметь то же имя пакета, что и идентификатор пакета. Ему также нужен идентификатор appstore, который вы можете получить из itunes, он должен отображаться в качестве префикса для профиля обеспечения ваших приложений. Если ваше приложение правильно настроено, например, с помощью мастера сертификатов Codename One, вы должны увидеть его в свойствах проекта в разделе Codename One → iOS.
После того, как все будет завершено, вы должны увидеть нечто похожее на это:
Конфигурация проекта
Теперь нам нужно установить несколько важных советов по сборке в проекте, чтобы он работал правильно. Чтобы установить подсказки для сборки, просто щелкните правой кнопкой мыши проект, выберите свойства проекта и в разделе Codename One выберите вторую вкладку. Добавьте эти записи в таблицу:
|
1
2
|
android.includeGPlayServices=trueios.gplus.clientId=your ios client ID |
Код
Так что теперь, когда все это на месте, мы бы хотели, чтобы оно работало с нашей сборкой …
Сначала, чтобы сделать код более общим, мы определим этот интерфейс, который мы можем реализовать как для Facebook, так и для Google, таким образом обобщая код входа в систему:
|
1
2
3
4
5
6
|
static interface UserData { public String getName(); public String getId(); public String getImage(); public void fetchData(String token, Runnable callback);} |
Способ работы этого интерфейса заключается в том, что мы вызываем fetchData после завершения процесса входа в систему, чтобы получить данные из Google / Facebook, а затем предоставить нам имя / идентификатор и изображение. Обратите внимание, что, поскольку Facebook не всегда предоставляет электронную почту, мы не можем надежно использовать ее в качестве уникального идентификатора для пользователя …
Также обратите внимание, что fetchData является асинхронным и будет вызывать обратный вызов после его завершения. Мы могли бы сделать это синхронно и использовать invokeAndBlock .
Код, который привязывает это к кнопке, выглядит следующим образом:
|
1
2
3
4
5
6
7
|
loginWithGoogle.addActionListener((e) -> { Login gc = GoogleConnect.getInstance(); gc.setClientId("1013232201263-lf4aib14r7g6mln58v1e36ibhktd79db.apps.googleusercontent.com"); gc.setClientSecret("-------------------"); doLogin(gc, new GoogleData());}); |
Обратите внимание, что мы спрятали клиент в GoogleData и использовали класс GoogleData который фактически является реализацией интерфейса UserData . Класс GoogleData выглядит следующим образом:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
static class GoogleData extends ConnectionRequest implements UserData { private Runnable callback; private Map<String, Object> parsedData; @Override public String getName() { return (String) parsedData.get("displayName"); } @Override public String getId() { java.util.List<Map<String, String>> emailList = (java.util.List<Map<String, String>>) parsedData.get("emails"); return emailList.get(0).get("value").toLowerCase(); } @Override public String getImage() { Map<String, Object> imageMeta = ((Map<String, Object>) parsedData.get("image")); return (String)imageMeta.get("url"); } @Override public void fetchData(String token, Runnable callback) { this.callback = callback; addRequestHeader("Authorization", "Bearer " + token); setPost(false); NetworkManager.getInstance().addToQueue(this); } @Override protected void readResponse(InputStream input) throws IOException { JSONParser parser = new JSONParser(); parsedData = parser.parseJSON(new InputStreamReader(input, "UTF-8")); } @Override protected void postResponse() { callback.run(); }} |
Как правило, в классе не так уж много. fetchData использует запрос на подключение для подключения к URL-адресу в Google+ API, который возвращает сведения о пользователе, когда токен установлен. Эти детали возвращаются в виде строки JSON, которую мы затем анализируем и устанавливаем для правильных переменных.
Класс JSONParser возвращает данные JSON в виде дерева списков и карт, через которое мы можем пройти, чтобы извлечь нужные нам данные.
Одно значение, которое может быть непонятным для случайного наблюдателя, — это token , это строка, содержащая «ключ» к учетной записи пользователя. Facebook / Google и т. Д. Хранят пароли своих пользователей в своей базе данных (фактически, даже если они не знают паролей), поэтому, чтобы доказать, что мы получили разрешение пользователя на доступ к его данным, мы получаем уникальный токен, который выглядит следующим образом: длинная строка тарабарщины, и мы можем использовать это при доступе к их соответствующим API, таким образом проверяя себя. Это очень распространенная практика … Однако токены иногда теряют силу, и поэтому вам может потребоваться «обновить» свой токен, выполнив вход снова, как показано в следующем блоке кода.
Теперь мы можем перейти к фактическому процессу входа в систему, который является общим для входа в Google и Facebook благодаря классу выше и встроенным абстракциям в Codename One:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
private String fullName;private String uniqueId;private String imageURL;void doLogin(Login lg, UserData data) { if(lg.isUserLoggedIn()) { showContactsForm(); return; } // if the user already logged in previously and we have a token String t = Preferences.get("token", (String)null); if(t != null) { // we check the expiration of the token which we previously stored as System time long tokenExpires = Preferences.get("tokenExpires", (long)-1); if(tokenExpires < 0 || tokenExpires > System.currentTimeMillis()) { // we are still logged in showContactsForm(); return; } } lg.setCallback(new LoginCallback() { @Override public void loginFailed(String errorMessage) { Dialog.show("Error Logging In", "There was an error logging in: " + errorMessage, "OK", null); } @Override public void loginSuccessful() { // when login is successful we fetch the full data data.fetchData(lg.getAccessToken().getToken(), ()-> { // we store the values of result into local variables uniqueId = data.getId(); fullName = data.getName(); imageURL = data.getImage(); // we then store the data into local cached storage so they will be around when we run the app next time Preferences.set("fullName", fullName); Preferences.set("uniqueId", uniqueId); Preferences.set("imageURL", imageURL); Preferences.set("token", lg.getAccessToken().getToken()); // token expiration is in seconds from the current time, we convert it to a System.currentTimeMillis value so we can // reference it in the future to check expiration Preferences.set("tokenExpires", tokenExpirationInMillis(lg.getAccessToken())); showContactsForm(); }); } }); lg.doLogin();} |
Теперь это большой блок кода, но на самом деле это не так уж и много. Все, что он делает — это делегирует интерфейс UserData и проверяет токен. Он также хранит возвращенные данные и показывает следующую форму (которую мы не будем сейчас рассматривать).
Последний фрагмент кода для этого раздела — это небольшой служебный метод, который мы использовали для определения истечения срока действия токена:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
/** * token expiration is in seconds from the current time, we convert it to a System.currentTimeMillis value so we can * reference it in the future to check expiration */long tokenExpirationInMillis(AccessToken token) { String expires = token.getExpires(); if(expires != null && expires.length() > 0) { try { // when it will expire in seconds long l = Long.parseLong(expires) * 1000; return System.currentTimeMillis() + l; } catch(NumberFormatException err) { // ignore invalid input } } return -1;} |
Это эффективно позволяет нам определить, истек ли токен в будущем выполнении приложения.
Другие сообщения в этой серии
Это непрерывная серия постов, включающая следующие части:
- Часть 1 — Начальный интерфейс
- Часть 2 — Войти через Google
- Часть 3 — Войти через Facebook (скоро)
| Ссылка: | Создание приложения для чата с кодовым названием One Part 2 от нашего партнера JCG Шая Альмога из блога Codename One . |










