2

在我的Web應用程序中,我希望用戶使用他們的Facebook帳戶登錄。我正在通過重定向url來做到這一點。我如何獲得access_token然後使用它?

response.sendRedirect("http://www.facebook.com/dialog/oauth/?scope=email,user_about_me&dispplay=popup&client_id={app_id}&redirect_uri=http://example.com/index.jsp&response_type=token"); 

在index.jsp我得到access_token在url中。但在請求中沒有訪問令牌。我如何獲得訪問令牌,然後獲取用戶的電子郵件。 index.jsp處的URL如下所示:

http://example.com/index.jsp#access_token={access_token} 

在此先感謝。

回答

1

facebook authentication guide顯示您應該將令牌獲取爲請求參數。只是不要使用response_type=token

+0

好的。我使用了response_type = code。並且我得到了代碼作爲請求參數。現在如何獲得令牌? – Piscean

+0

http://pinoyphp.blogspot.com/2010/12/oath-tutorial-how-to-get-facebook.html我發現這個教程,但我有點困惑。我得到的代碼,但那我怎麼得到access_token。如果我嘗試將它重定向到其他一些servlet,那麼它會給出錯誤。這意味着request_uri應該與獲取代碼和access_token相同。怎麼可能?它將像對同一頁面的無限呼叫一樣。不是嗎? – Piscean

2

其實我剛剛得到這個工作在我的JSP的項目!好的這是你需要知道的。你正在嘗試的方法被稱爲「服務器端」方法(也有一個客戶端方法,它可以共享很多相同的代碼,有兩個URL將被使用(我已經將這一切都包裝到了一個幫助程序中歸我叫FacebookConfig讀取它從一個facebook.properties文件需要:

import java.io.IOException; 
import java.io.InputStream; 
import java.util.Properties; 

import lombok.Cleanup; 
import st.fan.model.users.Listener; 

public class FacebookConfig { 
    public static String auth_uri; 
    public static String id; 
    public static String key; 

    static{ 
    Properties properties = new Properties(); 
    try { 
     @Cleanup InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("facebook.properties"); 
     properties.load(in); 
     auth_uri = (String)properties.get("auth_uri"); 
     id = (String)properties.get("id"); 
     key = (String)properties.get("key"); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } 

    public static String getOAuthDialogUrl() { 
    return "https://www.facebook.com/dialog/oauth?client_id="+id+"&redirect_uri="+auth_uri+"&scope=email"; 
    } 

    public static String getOAuthUrl(String code) { 
    return "https://graph.facebook.com/oauth/access_token?client_id="+id+"&redirect_uri="+auth_uri+"&client_secret="+key+"&code="+code; 
    } 

    public static String getGraphUrl(String token) { 
    return "https://graph.facebook.com/me?access_token="+token; 
    } 

    public static String getProfilePictureUrl(Listener profile) { 
    return "https://graph.facebook.com/"+profile.getFacebookId()+"/picture"; 
    } 

    public static String getProfilePictureUrl(Listener profile, String size) { 
    return "https://graph.facebook.com/"+profile.getFacebookId()+"/picture?type="+size; 
    } 
} 

現在,用戶被重定向到包含一個名爲http://example.com/auth/facebook/Auth的servlet具有這種的doGet的URL getOAuthDialogUrl()()方法

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 
    Transaction tx = null; 
    Session dao = SessionFactoryUtil.getInstance().getCurrentSession(); 
    String redirect = "/auth/facebook/sorry"; 

    try { 
    String code = request.getParameter("code"); 
    if(code != null) { 
     String[] pairs = NetUtils.fetch(new URL(FacebookConfig.getOAuthUrl(code))).toString().split("&"); 
     String accessToken = null; 
     Integer expires = null; 
     for (String pair : pairs) { 
     String[] kv = pair.split("="); 
     if (kv.length == 2) { 
      if (kv[0].equals("access_token")) { 
      accessToken = kv[1]; 
      } 
      if (kv[0].equals("expires")) { 
      expires = Integer.valueOf(kv[1]); 
      } 
     } 
     } 
     if(accessToken != null && expires != null) { 
     try { 
      JSONObject fb_profile = new JSONObject(NetUtils.fetch(new URL(FacebookConfig.getGraphUrl(accessToken)))); 
      tx = dao.beginTransaction(); 
      ListenerSession session = authenticate(request, dao); 
      if(session == null) { 
      session = createSession(response, dao); 
      } 
      String facebookid = fb_profile.getString("id"); 
      String name = fb_profile.getString("name"); 
      String email = fb_profile.getString("email"); 
      String username = facebookid; 
      if(fb_profile.has("username")) { 
      username = fb_profile.getString("username"); 
      } 
      Listener user = ListenerDAO.findByFacebookId(facebookid, dao); 
      if(user != null) { 
      user.setDisplayName(name); 
      user.setEmail(email); 
      dao.save(user); 
      } else { 
      user = new Listener(); 
      user.setUsername(username); 
      user.setDisplayName(name); 
      user.setEmail(email); 
      user.setDateCreated(new DateTime()); 
      user.setFacebookId(facebookid); 
      user.setStatus(ListenerStatus.ACTIVE); 
      dao.save(user); 
      } 
      ListenerSessionDAO.link(session, user, dao); 
      redirect = "/"; 
      tx.commit(); 
     } catch (JSONException e) { 
      log.error("Parsing Facebook Graph Response", e); 
     } 
     } else { 
     log.error("Expected values not found!"); 
     log.error("accessToken="+accessToken); 
     log.error("expires="+expires); 
     } 
    } else { 
     log.error("Missing 'code' param!"); 
    } 
    } catch(Exception e) { 
    e.printStackTrace(System.out); 
    } finally { 
    if(dao.isOpen()) { 
     dao.close(); 
    } 
    } 
    response.sendRedirect(redirect); 
} 

而且(除了使用Hibernate,龍目島項目和一個簡單的JSON庫調用org.json )我使用一個稱爲一個簡單的輔助函數取(),接受一個URL,並返回內容爲具有該代碼的字符串:

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.URL; 
import java.net.URLConnection; 

public class NetUtils { 
    public static String fetch(URL url) throws IOException { 
    URLConnection connection = url.openConnection(); 
    String line; 
    StringBuilder builder = new StringBuilder(); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); 
    while((line = reader.readLine()) != null) { 
     builder.append(line); 
    } 
    return builder.toString(); 
    } 
} 

這應該讓你離開地面:)

+0

從哪裏可以得到st.fan.model.users.Listener jar? – Piscean

+0

我在實現這個問題的答案後得到了這麼多,我發佈了http://stackoverflow.com/questions/5184959/facebook-connect-example-in-jsp-tomcat Listener類基本上是我談論的Profile類。 –

1

只打印$ _REQUEST ['signed_request']數組,其中有oauth。這是你的主動訪問令牌使用它在你想要的地方..

我自己花了兩天就可以了,最後得到它

相關問題