需求:使用spring social facebook;集成多个社会化组件,如 Twitter等
解决方案:
问题一:仅使用spring social facebook
1)下载相关包http://www.springsource.org/spring-social/
2)解决oauth2登陆获取令牌问题:方案有两个,
一是直接使用httpClient取访问,二是使用spring social提供的组件:
a.添加链接:
<a href="https://www.facebook.com/dialog/oauth?client_id=${facebook_client_id!}&redirect_uri=${facebook_redirect_uri!}&state=${facebook_login_uuid!}"><img src="${base}/img/facebook.png" />登陆</a>
注意:可以不直接使用此路径,spring social提供了一个Controller,默认自动装配了一些路径,不过个人不建议使用;此<a>路径也可以放在action中隐藏起来,在服务器端使用httpClient访问,没测试,请自己尝试,spring的Controller默认是在后端处理此路径的
b.上面窗口会弹出facebook登陆窗口,使用自己的用户名账号登陆后,在服务器端回调路径中获取code,并使用code换取令牌。
@Autowired
FacebookConnectionFactory factory;
String code = request.getParameter("code");
String state = request.getParameter("state");
String tokenResult;
try {
tokenResult = accessTokenFacebook(code);//第一种方式使用httpClient
OAuth2Operations oauthOperations = factory.getOAuthOperations();//第二种方式使用spring
AccessGrant accessGrant = oauthOperations.exchangeForAccess(code, Propertyholder.getContextProperty("facebook.redirect_uri"), null);
Connection<Facebook> connection = factory.createConnection(accessGrant);
Facebook facebook = connection.getApi();//可以用它去访问facebook数据库了
ConnectionData connectionData=connection.createData();//这是访问权限信息可以放入缓存
JSONObject tokenJson = (JSONObject) JSONValue.parse(tokenResult);
if (tokenJson != null) {
String accessToken = (String) tokenJson.get("access_token");
Long expiresIn = (Long) tokenJson.get("expires_in");//距离过期时的时间段(秒数)
long currentTime = System.currentTimeMillis() / 1000;
long expiresTime = currentTime + expiresIn;//即将过期的时间点(秒数)
request.getSession().setAttribute("facebook_expires_time", expiresTime);
request.getSession().setAttribute("facebook_access_token", accessToken);
return "facebooktest.ftl";//非管理员用户返回到会员中心
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
private String accessTokenFacebook(String code) throws URISyntaxException, ClientProtocolException, IOException, ParseException{
String uri="https://graph.facebook.com/oauth/access_token?client_id="
+Propertyholder.getContextProperty("facebook.client_id")
+"&redirect_uri="+Propertyholder.getContextProperty("facebook.redirect_uri")
+"&client_secret="+Propertyholder.getContextProperty("facebook.client_secret")
+"&code="+code;
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(uri);
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
String str="";
if (entity != null) {
str=EntityUtils.toString(entity, "UTF-8");
}
return str;
}
注意:connectionData可以放入session以便下一次请求facebook数据时重用,和下面使用request.getSession().setAttribute("facebook_expires_time", expiresTime)是一个目的。
问题二:集成多个社会化组件,如 Twitter等。主要问题是解决多用户和多用的连接数据重用问题。
spring提供非常完善的工厂类用来创建和管理各种社交系统链接,如果是存关系数据库,可以直接采用spring的方案存在数据库中,另外也可以放二级缓存或者图形数据库中,但是需要自己实现spring的ConnectionRepository接口。
来源:oschina
链接:https://my.oschina.net/u/3808/blog/70161