GWT : Utiliser le compte Google de vos utilisateurs

GWTwitter0.5

GWTwitter0.5

Dans le dernier article de GWTwitter nous nous étions arrêté sur une application qui fonctionne et qui est pas trop moche (ou même jolie si vous avez poussé le dernier concept plus loin).

Aujourd’hui nous allons voir comme utiliser les Comptes Google de nos utilisateurs à travers l’API de Google App Engine. Nous pourrons ainsi demander à nos utilisateurs de s’authentifier avec les mêmes identifiants que GMail, Google Calendar ou tout autres applications de Google.

Commencez par récupérer la version 0.4 qui correspond au dernier article.

Refonte de l’architecture

Maintenant qu’on va avoir pas mal de classes il serait pas mal de créer une petite architecture de packages. Dans le package « client » nous allons donc créer deux sous-packages comme décrit ci-dessous :

  • client.object
    • Tweet.java -> GTTweet.java (on le renomme au passage)
    • GTUser.java (on va le créer ensuite)
  • client.rpc
    • GWTwitterService.java
    • GWTwitterServiceAsync.java
    • GTUserService.java (on va le créer ensuite)
    • GTUserServiceAsync.java (pareil)

Objet métier

Il existe une classe User dans l’API Google App Engine, cependant on ne peut pas l’utiliser directement du côté client puisqu’elle n’est pas adaptée pour fonctionner de ce côté. De plus, créer une classe  nous permettra, dans un futur article, de la stocker en base de données.

Certaines classes de Java sont utilisables du côté client (Boolean, String, Integer, etc.). Cependant elles fonctionnent du côté client car une version spéciale a été faite pour cette utilisation. Ce n’est pas le cas de la classe User de GAE.

Nous allons maintenant créer la classe GTUser qui implémente l’interface IsSerializable tout comme la classe GTTweet (aka Tweet). GTUser aura quatres attributs :

private String authDomain;
private String email;
private String nickname;
private String userId;

Elle aura besoin de deux constructeurs : un vide et un qui inclus tous les attributs définis ci-dessus. Vous aurez aussi besoin de générer les Getter et Setter (Eclipse peut le faire pour vous).

Allons maintenant dans la classe GTTweet pour y ajouter une référence vers GTUser :

public class GTTweet implements IsSerializable {
 
	private String text;
	private Date date;
	private GTUser user;
 
	public GTTweet() {}
 
	public GTTweet(String text, GTUser user) {
		this.text = text;
		this.setDate(new Date());
		this.user = user;
	}
 
	public String getText() {
		return text;
	}
	public void setText(String text) {
		this.text = text;
	}
	public void setDate(Date date) {
		this.date = date;
	}
	public Date getDate() {
		return date;
	}
	public GTUser getUser() {
		return user;
	}
	public void setUser(GTUser user) {
		this.user = user;
	}
 
}

Classes RPC

Nos objets sont fins prêts. Nous allons maintenant passer à la définition puis à l’implémentation de notre classe RPC qui gérera le compte utilisateur.

Définition

La définition de la classe RPC se fait toujours du côté client. C’est de ce côté que nous allons créer les Interfaces et donc définir quelles seront les méthodes à implémenter du côté serveur.

Créons donc, dans le package rpc, une première Interface « GTUserService » qui étend « RemoteService ». Normalement, a ce moment là Eclipse vous informe d’un problème et  vous demander de créer la version asynchrone de « GTUserService ». Cliquez pour le laisser créer.

A chaque fois que nous allons créer une nouvelle méthode à la première Interface, Eclipse voudra la copier sur la version asynchrone. Laissez le faire, ça vous fera du travail en moins.

GWT - génération automatique de code

GWT - génération automatique de code

Ajoutez les méthodes suivantes dans GTUserService :

String createLoginURL(String callbackUrl);
String createLoginURL(String callbackUrl, String authDomain);
String createLogoutURL(String callbackUrl);
String createLogoutURL(String destinationURL, String authDomain);
 
GTUser getCurrentUser();
boolean isUserAdmin();
boolean isUserLoggedIn();

Ce sont ces méthodes que nous allons appeler via l’interface asynchrone pour récupérer l’utilisateur connecté, pour le rediriger vers la page de connexion ou le déconnecter.

Implémentation

Attaquons-nous maintenant à la partie serveur du service, ça va se passer dans le package « server » de l’application. Créez une classe qui étend « RemoteServiceServlet » et qui implémente « GTUserService ».

Si vous choisissez les classes à étendre et les interfaces à implémenter dès la création de vote classe, Eclipse s’occupera de créer lui-même les méthodes à implémenter en les remplissant avec un contenu par défaut.

GWT - Création d'un service

GWT - Création d'un service

Créez donc cette classe :

public class GTUserServiceImpl
	extends RemoteServiceServlet
	implements GTUserService

Nous allons utiliser dans chacune des méthodes de cette classe un outil de GAE : Le UserService. C’est une des API proposées par GAE, elle nous permet d’avoir accès à quelques infos des comptes Google. Nous utiliseront donc une variable de classe que nous instancierons de la façon suivante :

public class GTUserServiceImpl
	extends RemoteServiceServlet
	implements GTUserService {
 
		private final static UserService userService = UserServiceFactory.getUserService();
 
		/* Reste de la classe... */
 
}

Voici le contenu de cette classe, ce n’est qu’une implémentation simple de l’interface créée ci-dessus. Rien de bien compliqué, pas besoin d’explication, le code parle de lui-même :

package me.gwtwitter.server;
 
import me.gwtwitter.client.object.GTUser;
import me.gwtwitter.client.rpc.GTUserService;
 
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
 
public class GTUserServiceImpl extends RemoteServiceServlet implements GTUserService {
 
	private static final long serialVersionUID = 1L;
 
	private final static UserService userService = UserServiceFactory.getUserService();
 
	@Override
	public String createLoginURL(String callbackUrl) {
		return userService.createLoginURL(callbackUrl);
	}
 
	@Override
	public String createLoginURL(String callbackUrl, String authDomain) {
		return userService.createLoginURL(callbackUrl, authDomain);
	}
 
	@Override
	public String createLogoutURL(String callbackUrl) {
		return userService.createLogoutURL(callbackUrl);
	}
 
	@Override
	public String createLogoutURL(String destinationURL, String authDomain) {
		return userService.createLogoutURL(destinationURL, authDomain);
	}
 
	@Override
	public GTUser getCurrentUser() {
		final User user = userService.getCurrentUser();
		return new GTUser(
				user.getAuthDomain(),
				user.getEmail(),
				user.getNickname(),
				user.getUserId()
			);
	}
 
	@Override
	public boolean isUserAdmin() {
		return userService.isUserAdmin();
	}
 
	@Override
	public boolean isUserLoggedIn() {
		return userService.isUserLoggedIn();
	}
 
}

Utilisation du service

A la création d’un tweet

Nous allons utiliser une première fois ce service pour récupérer le compte de la personne qui ajoute un tweet :

public class GWTwitterServiceImpl extends RemoteServiceServlet implements GWTwitterService {
 
	/* ..... */
 
	private static final GTUserServiceImpl userService = new GTUserServiceImpl();
 
	/* ..... */
 
	@Override
	public void newTweet(String text) {
		if (!text.trim().isEmpty()) {
			tweets.add(0, new GTTweet(text, userService.getCurrentUser()));
		}
	}
}

Dans le module

Nous allons maintenant utiliser ce service dans l’EntryPoint pour limiter l’utilisation de notre application aux utilisateurs ne possédant pas de compte Google.

Je vous propose un nouveau fonctionnement :

  • L’utilisateur n’est pas connecté
    • Il peut voir les tweets
    • Il ne voit pas le formulaire, mais un bouton « Se connecter »
  • L’utilisateur est connecté
    • Il peut ajouter des tweets
    • Il voit un bouton « Se déconnecter »

Commencez par ajouter les deux nouveaux boutons à votre EntryPoint (client.GWTwitter) ainsi que l’objet qui nous donnera accès au service crée dans cet article :

	private final GTUserServiceAsync userService = GWT.create(GTUserService.class);
 
	private final Button loginButton = new Button("Connect Me");
	private final Button logoutButton = new Button("Log out");

Dans cet article, nous utiliseront le Panel « addPanel » pour mettre tous les composants qui concerne la connexion/déconnexion. Nous allons donc vider ce Panel. Supprimez les lignes du genre addPanel.add(…); .

Définissons maintenant quelles sont les actions à faire sur les deux boutons de connexion/déconnexion :

	public void onModuleLoad() {
		/* ..... */
		loginButton.addClickHandler(new ClickHandler() {
 
			@Override
			public void onClick(ClickEvent event) {
				userService.createLoginURL("/", new AsyncCallback() {
 
					@Override
					public void onSuccess(String loginURL) {
						Window.open(loginURL, "_self", "");
					}
 
					@Override
					public void onFailure(Throwable caught) {
						Window.alert(caught.getMessage());
					}
				});
			}
		});
		logoutButton.addClickHandler(new ClickHandler() {
 
			@Override
			public void onClick(ClickEvent event) {
				userService.createLogoutURL("/", new AsyncCallback() {
 
					@Override
					public void onSuccess(String logoutURL) {
						Window.open(logoutURL, "_self", "");
					}
 
					@Override
					public void onFailure(Throwable caught) {
						Window.alert(caught.getMessage());
					}
				});
			}
		});
	}

Lorsque vous cliquerez sur le bouton de connexion, nous allons appeler le service pour qu’il nous donne l’adresse à laquelle l’utilisateur peut s’identifier. Dès la réponse du service nous redirigeons l’utilisateur vers cette adresse : Window.open(loginURL, « _self », «  »); .

Le « / » indique qu’après s’être authentifié, l’utilisateur sera redirigé vers la racine de notre site. Si vous souhaitez une autre adresse vous pouvez faire un truc du genre « /monmodule.html ».

Le bouton de déconnexion fonctionne de la même façon.

Ensuite nous pouvons appeler le service pour vérifier si oui ou non l’utilisateur est connecté avec son compte Google :

	public void onModuleLoad() {
		/* ..... */
		userService.isUserLoggedIn(new AsyncCallback() {
 
			@Override
			public void onSuccess(Boolean result) {
				if (result) {
					addPanel.clear();
					addPanel.add(tweetTextBox);
					addPanel.add(submitButton);
					addPanel.add(logoutButton);
				} else {
					addPanel.clear();
					addPanel.add(loginButton);
				}
			}
 
			@Override
			public void onFailure(Throwable caught) {
				addPanel.clear();
				addPanel.add(new Label("Problem with the connection"));
			}
		});
	}

Pour nous rendre compte que tout marche bien, il faut maintenant ajouter le « nickname » de la personne qui a rédigé le tweet dans le tableau :

	tweetsTable.setText(0, 0, "User");
	tweetsTable.setText(0, 1, "Tweet");
	tweetsTable.setText(0, 2, "Date");
 
	/* ..... */
 
	tweetsTable.getColumnFormatter().addStyleName(2, "tweetsTableHeaderDate");
 
	/* ..... */
 
	tweetsTable.setText(i, 0, tweet.getUser()).getNickname();
	tweetsTable.setText(i, 1, tweet.getText());
	tweetsTable.setText(i, 2, DateTimeFormat.getMediumDateTimeFormat().format(tweet.getDate()));

Le code ci-dessus ne montre que les changements opérés.

Plus qu’une dernière étape, il ne nous reste qu’à faire le mapping dans le fichier web.xml. C’est à dire, définir quelle classe est associée à quelle adresse :

<servlet>
	<servlet-name>userService</servlet-name>
	<servlet-class>me.gwtwitter.server.GTUserServiceImpl</servlet-class>
</servlet>
 
<servlet-mapping>
	<servlet-name>userService</servlet-name>
	<url-pattern>/gwtwitter/userService</url-pattern>
</servlet-mapping>

Et comme à chaque fin d’article de GWTwitter, vous pouvez télécharger le résultat en version 0.5 pour pouvoir étudier son code ou bien le modifier.

Tagués avec : , , , , ,
Publié dans Google Web Toolkit
2 commentaires pour “GWT : Utiliser le compte Google de vos utilisateurs
  1. Peter Grais dit :

    J’ai voulu suivre les instructions pour passer de la version 0.4 à 0.5 et j’ai été embête avec cette ligne : « Ajoutez les méthodes suivantes dans GTUserServer ».
    Finalement, j’ai vu à la fin de l’article qu’on pouvait télécharger la version 0.5 complète, et il semble que c’est dans « GTUserService » qu’il faut ajouter les méthodes.
    Sinon merci pour cet article, c’est exactement ce dont j’avais besoin !

  2. Olivier PEREZ dit :

    Ok merci bien, je viens de faire la correction. En ce qui concerne les articles de GWT je pense que je vais faire une pause, je me suis lancé dans Android et j’en suis tombé amoureux.
    D’ailleurs un article à ce sujet devrait bien être publié.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*