Caros,
Depois de muito bater cabeça e muitos tutoriais depois, consegui criar um projeto que utiliza o protocolo OAuth e a API do Facebook para efetuar login em uma aplicação Web. Curtam o tutorial.
O que eu utilizei:
- Netbeans 7.1.2
- Java 7
- Facebook-api-3.0.4
- Primefaces 3.3.1
- RestFb 1.6.9
- Maven
- Glassfish 3.1.2
- JSF 2
Passo 1.
Crie um projeto web Maven através do menu: Arquivo -> Novo Projeto -> Maven -> Aplicação Web. Siga os passos selecionando o Glassfish e afins (não entrarei no cerne da criação de um projeto web).
Passo 2.
Edite o arquivo pom.xml adicionando os seguintes repositórios e dependências:
<repositories>
<repository>
<id>prime-repo</id>
<name>PrimeFaces Maven Repository</name>
<url>http://repository.primefaces.org</url>
<layout>default</layout>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.restfb</groupId>
<artifactId>restfb</artifactId>
<version>1.6.9</version>
</dependency>
<dependency>
<groupId>com.google.code.facebookapi</groupId>
<artifactId>facebook-java-api</artifactId>
<version>3.0.4</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>freemaker</groupId>
<artifactId>freemaker</artifactId>
<version>2.3.8</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>br.com.xpert</groupId>
<artifactId>xpertframework</artifactId>
<version>1.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-api</artifactId>
<version>2.10</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>3.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Passo 3. Crie uma Classe chamada UsuarioFB, essa classe irá armazenar os dados provindos do Facebook:
public class Usuario {
@Facebook
private String id;
@Facebook
private String name;
@Facebook
private String email;
A Anotação @Facebook provém do RestFB, um biblioteca que encontrei nas minhas pesquisas na web e muito me ajudou. Mais informações em: RestFB.com
Passo 4. Crie um ManagedBean que irá gerenciar o usuário logado da aplicação:
@ManagedBean
@SessionScoped
public class LoginController {
private String login;
private String senha;
private Usuario usuario;
Observação!!! Nunca se esqueça de implementar os métodos getters e setters!!!
Passo 4. Configure sua aplicação no Facebook, para isso acesse o link: Facebook Developers. Tutorial bom: Tutorial Configuração Aplicação. Esse passo irá gerar uma API_KEY e uma API_SECRET.
Passo 5. Crie um Classe chamada FaceBookClient que irá gerir os métodos de conexão e obtenção do token de acesso:
public class FaceBookClient {
public static String API_KEY = “SUA API KEY”;
public static String SECRET = “SUA API SECRET”;
private static final String client_id = “SEU CLIENT ID”;
// set this to your servlet URL for the authentication servlet/filter
private static final String redirect_uri = “SUA URL DE RETORNO (pode ser o locahost)”;
/// set this to the list of extended permissions you want
private static final String[] perms = new String[]{“publish_stream”, “email”};
public static String getAPIKey() {
return API_KEY;
}
public static String getSecret() {
return SECRET;
}
public static String getLoginRedirectURL() {
return “https://graph.facebook.com/oauth/authorize?client_id=”
+ API_KEY + “&display=page&redirect_uri=”
+ redirect_uri + “&scope=publish_stream, email”;
}
public static String getAuthURL(String authCode) {
return “https://graph.facebook.com/oauth/access_token?client_id=”
+ API_KEY + “&redirect_uri=”
+ redirect_uri + “&client_secret=” + SECRET + “&code=” + authCode;
}
Passo 6. Implementaremos agora um Filter que irá receber a resposta do Facebook.
public class FacebookFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest sr, ServletResponse sr1, FilterChain fc) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) sr;
HttpServletResponse res = (HttpServletResponse) sr1;
String code = sr.getParameter(“code”);
if (code != “”) {
String authURL = FaceBookClient.getAuthURL(code);
URL url = new URL(authURL);
try {
String result = readURL(url);
String accessToken = null;
Integer expires = null;
String[] pairs = result.split(“&”);
for (String pair : pairs) {
String[] kv = pair.split(“=”);
if (kv.length != 2) {
throw new RuntimeException(“Unexpected auth response”);
} else {
if (kv[0].equals(“access_token”)) {
accessToken = kv[1];
}
if (kv[0].equals(“expires”)) {
expires = Integer.valueOf(kv[1]);
}
}
}
if (accessToken != null && expires != null) {
Usuario u = new Usuario();
UsuarioService us = new UsuarioService();
us.authFacebookLogin(accessToken, expires);
res.sendRedirect(“AQUI COLOQUE A URL DE RETORNO depois do login, por exemplo: http://localhost:8080/LoginFacebook/logado.jsf”);
} else {
throw new RuntimeException(“Access token and expires not found”);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private String readURL(URL url) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = url.openStream();
int r;
while ((r = is.read()) != -1) {
baos.write(r);
}
return new String(baos.toByteArray());
}
@Override
public void destroy() {
}
}
Passo 7. Configure o Filter no web.xml:
<filter>
<filter-name>FacebookFilter</filter-name>
<filter-class>br.com.estudos.filter.FacebookFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FacebookFilter</filter-name>
<url-pattern>/login/*</url-pattern>
</filter-mapping>
Passo 8. Implementemos agora o método que efetua o login no ManagedBean, adicione o seguinte código no ManagedBean:
public String conectarComFace() {
return FaceBookClient.getLoginRedirectURL();
}
Passo 9. Perceba que na configuração do Filter colocamos para ele atuar em um diretório chamado login, isso força nossa implementação a url de redirecionamento (configurada no passo 5) ser redirecionada para uma página dentro desse diretório. Portanto, crie esse diretório na sua aplicação.
Passo 10. Crie as páginas para efetuar o Login que deve conter um commandLink:
<h:outputLink value=”#{loginController.conectarComFace()}”>
Login com FaceBook
</h:outputLink>
A página logado (como configurado no passo 6) contém apenas a palavra `Logado`.
Passo 11. Criaremos um UsuarioService, reponsável pela consulta dos dados do usuário:
public class UsuarioService {
public void authFacebookLogin(String accessToken, int expires) {
try {
FacebookClient fb = new DefaultFacebookClient(accessToken);
Usuario user = fb.fetchObject(“me”, Usuario.class);
System.out.println(user);
} catch (Throwable ex) {
throw new RuntimeException(“failed login”, ex);
}
}
}
O código do exemplo está aqui: LoginFacebook!
Enjoy!