公司的一个项目要求在系统中加上Facebook的登陆功能。研究了好久,中间空空闲闲的大概花了三个星期的样子,也不是全部时间都在这个上面。感觉时间主要是浪费在取数据上面,网络原因占八成。数据可以拿到,但是要连上自己的电脑真的是费劲的很。主要是不懂得要连接facebook还需要代理(针对中国的,如果服务器在外国就不需要了)。
用的是Facebook OAuth 2.0。(http://developers.facebook.com/docs/authentication/)。
下载这个visural-common(地址:http://code.google.com/p/visural-common/)
library for some of the code 。
首先建一个基本类:
public
class Facebook
{
// get these from your FB Dev App
private
static final
String api_key =
"MYAPIKEY";
private
static final
String secret =
"MYSECRETKEY";
private
static final
String client_id =
"MYCLIENTID";
// set this to your servlet URL for the authentication servlet/filter
private
static final
String redirect_uri =
"http://www.onmydoorstep.com.au/fbauth";
/// 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="
+
client_id +
"&display=page&redirect_uri="
+
redirect_uri+"&scope="+StringUtil.delimitObjectsToString(",",
perms);
}
public
static String getAuthURL(String authCode)
{
return
"https://graph.facebook.com/oauth/access_token?client_id="
+
client_id+"&redirect_uri="
+
redirect_uri+"&client_secret="+secret+"&code="+authCode;
}
}
用来存放一个注册的基本信息的bo(开发人员,创建app时,产生的一些信息,还有就是在自己的项目中创建一个servlet).
Servlet如下:
public
class FBOAuth
implements Filter
{
public
void init(FilterConfig fc)
throws ServletException
{
}
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
(StringUtil.isNotBlankStr(code))
{
String authURL
= Facebook.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)
{
UserService us
= UserService.get();
us.authFacebookLogin(accessToken,
expires);
res.sendRedirect("http://www.onmydoorstep.com.au/");
}
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());
}
public
void destroy()
{
}
}
UserService如下:
class
UserService {
// ....
public
void authFacebookLogin(String accessToken,
int expires)
{
try
{
JSONObject resp
= new
JSONObject(
IOUtil.urlToString(new URL("https://graph.facebook.com/me?access_token="
+ accessToken)));
String id
= resp.getString("id");
String firstName
= resp.getString("first_name");
String lastName
= resp.getString("last_name");
String email
= resp.getString("email");
// ...
// create and authorise the user in your current system w/ data above
// ...
}
catch (Throwable ex)
{
throw
new RuntimeException("failed login", ex);
}
}
}
具体也是引用别人的代码:(http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/)不过我安照他的思想成功了。没有贴自己的代码,是因为我的代码中,业务逻辑比较乱,怕粘出来,影响大家看懂这个流程。
具体的流程(http://developers.facebook.com/docs/authentication/)
具体参数的获取看这个(http://developers.facebook.com/docs/reference/api/)
用java实现参数用的就是上面提供的一个jar包。