网易微博最近也开放了它的开发平台
http://open.t.163.com,其中java版的oauth认证和新浪微博的很类似(貌似都是从twitter那边copy过来的)。但说句实话,网易java版的sdk和新浪微博的比起来,的确上手比较麻烦,里面提供的example都是把access token写死,作为参数,具体的代码如下:
public static void main(String[] args){
System.setProperty("tblog4j.oauth.consumerKey", "EJ0GpH9mtU584qtY");
System.setProperty("tblog4j.oauth.consumerSecret", "EgIdvwgF6UXc6WMZs6jTv5ivZcNVDvnT");
TBlog tblog = new TBlog();
tblog.setToken("46f29fb418bdb14044bf39d2cad49f81", "f0c81ad9783f1s427da38312c0cc910c");
try {
tblog.updateStatus("update status from Java SDK");
} catch (TBlogException e) {
e.printStackTrace();
}
}
完全没有体现出oauth的完整认证过程,access token(就是46f29fb418bdb14044bf39d2cad49f81,f0c81ad9783f1s427da38312c0cc910c"两段字符串)是怎么来的,完全没有演示的过程,搞得我做这个开发的时候只能摸黑,其实oauth的完整过程是这样的:
OAuth流程图
- A:消费方请求Request Token
- B:服务提供者授权Request Token
- C:消费方定向用户到服务提供者
- D:获得用户授权后,服务提供者定向用户到消费方
- E:消费方请求Access Token
- F:服务提供者授权Access Token
- G:消费方访问受保护的资源
具体的请去围观这篇文章http://huoding.com/2010/10/10/8.
由于开发受阻,只好求助它的兄弟sdk,那就是新浪微博的sdk,但两者虽然相似度很高,但到底在细节处还是有所不同,下面就是我仿造新浪微博网页oauth认证的网易版。
这个过程首先是要在网易开发平台申请消费者开发的key和secret字符串,谁都可以去上面的网易开发平台申请:申请到的画面如下:
然后就可以构造一个jsp的页面,这个页面就是调用oauth认证的,我这个jsp叫call.jsp,具体的jsp代码如下:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ page language="java" import="t4j.*" %>
<%@ page language="java" import="t4j.http.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
System.setProperty("tblog4j.oauth.consumerKey", "EJ0GpH9mtU123xxx");
System.setProperty("tblog4j.oauth.consumerSecret", "EgIdvwgF6UXc6WMZs6jTv5ivZcxxxxxx");
TBlog tblog = new TBlog();
try {
RequestToken requestToken = tblog.getOAuthRequestToken();
session.setAttribute("requestToken",requestToken);
String url = "http://api.t.163.com/oauth/authenticate?oauth_token="+requestToken.getToken()+"&oauth_token_secret="+requestToken.getTokenSecret()+"&oauth_callback=http%3A%2F%2Flocalhost%3A8080%2F163%2Fcallback.jsp";
response.sendRedirect(url);
} catch (TBlogException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
%>
</body>
</html>
这个页面就是把申请来的consumerKey和consumerSecret传到一个TBlog对象,这个对象就是网易微博的接口对象了,所有oauth认证以及网易微博的操作api都在这个类中。传递过去后就能够得到request token,同时把requestToken存到session里面,方便后面的页面使用。接下来就是oauth的认证了,需要把requestToken和requestTokenSecret(两个字符串,在requestToken对象中)传递到网易的授权页面,记得带上oauth_callback参数,这个参数是通过认证后网易回调的页面,说明白一点,就是通过认证了,网易就会自己跳回到你oauth_callback里面传递的这个页面。然后就跳到网易的认证页面了。
需要输入网易通行证的用户名和密码,登录后就到了认证的页面了
点击允许后,就会跳回到oauth_callback参数传递的页面,我这个页面就是callback.jsp,代码如下:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ page language="java" import="t4j.*" %>
<%@ page language="java" import="t4j.http.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
RequestToken requestToken = (RequestToken)session.getAttribute("requestToken");
TBlog tblog = new TBlog();
AccessToken token = tblog.getOAuthAccessToken(requestToken);
tblog.setToken(token.getToken(),token.getTokenSecret());
try {
out.println(tblog.updateStatus("update status from Java SDK").getId());
} catch (TBlogException e) {
e.printStackTrace();
}
%>
</body>
</html>
在这个页面就可以去到通过了认证的AccessToken,有了这个,就算是通过了oauth认证,可以操作网易微博的各种资源了。requestToken存在session的意义就是为了在这个页面可以去到,并根据这个requestToken得到AccessToken,如果不经过网易的那个认证页面,直接用requestToken是得不到AccessToken(是的,我试过了直接取,没用的)。上面updateStaus就是发一条微博到网易去。
本来到这边就算完成了,但是如果我们需要通过接口搜索网易微博的内容时,比如这样:
List<Status> list = tblog.searchStatus("情人节");
那么你遇到的就是像一个人的情人节那样可耻的失败,当然上面如果是英语,是不会有问题的,但中文(中国程序员满脸都是泪,心里都是苦),错误代码是这样的:
[Wed Feb 16 21:15:25 CST 2011]Request:
[Wed Feb 16 21:15:25 CST 2011]GET http://api.t.163.com/search.json?q=情人节
[Wed Feb 16 21:15:25 CST 2011]OAuth base string:GET&http%3A%2F%2Fapi.t.163.com%2Fsearch.json&oauth_consumer_key%3DEJ0GpH9mtU584qtY%26oauth_nonce%3D1981498615%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1297862125%26oauth_token%3D3d5ec3c98e57d20c40c458bfe6999d66%26oauth_version%3D1.0%26q%3D%25E6%2583%2585%25E4%25BA%25BA%25E8%258A%2582
[Wed Feb 16 21:15:25 CST 2011]OAuth signature:XMJW2PnNi1TuL1kSkiwCmBbSejA=
[Wed Feb 16 21:15:25 CST 2011]Authorization: OAuth oauth_consumer_key="EJ0GpH9mtU584qtY",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1297862125",oauth_nonce="1981498615",oauth_version="1.0",oauth_token="3d5ec3c98e57d20c40c458bfe6999d66",oauth_signature="XMJW2PnNi1TuL1kSkiwCmBbSejA%3D"
[Wed Feb 16 21:15:25 CST 2011]TBlog-Client-URL: http://open.t.163.com
[Wed Feb 16 21:15:25 CST 2011]Accept-Encoding: gzip
[Wed Feb 16 21:15:25 CST 2011]User-Agent: tblog4j http://open.t.163.com
[Wed Feb 16 21:15:25 CST 2011]TBlog-Client-Version: 1.0
t4j.TBlogException: 401:Authentication credentials were missing or incorrect.
{"request":"/search.json?q=?é????","error":"oauth_signature=XMJW2PnNi1TuL1kSkiwCmBbSejA= oauth_signature_base_string=GET&http%3A%2F%2Fapi.t.163.com%2Fsearch.json&oauth_consumer_key%3DEJ0GpH9mtU584qtY%26oauth_nonce%3D1981498615%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1297862125%26oauth_token%3D3d5ec3c98e57d20c40c458bfe6999d66%26oauth_version%3D1.0 oauth_problem=signature_invalid oauth_signature_method=HMAC-SHA1","error_code":"401"}
at t4j.http.HttpClient.httpRequest(HttpClient.java:572)
[Wed Feb 16 21:15:25 CST 2011]Response:
[Wed Feb 16 21:15:25 CST 2011]HTTP/1.1 401 Unauthorized
[Wed Feb 16 21:15:25 CST 2011]Content-Language:
[Wed Feb 16 21:15:25 CST 2011]Date: Wed, 16 Feb 2011 13:15:33 GMT
[Wed Feb 16 21:15:25 CST 2011]Transfer-Encoding: chunked
[Wed Feb 16 21:15:25 CST 2011]Expires: Thu, 01 Jan 1970 00:00:00 GMT
[Wed Feb 16 21:15:25 CST 2011]Content-Type: application/json;charset=utf-8
[Wed Feb 16 21:15:25 CST 2011]Connection: keep-alive
[Wed Feb 16 21:15:25 CST 2011]Server: nginx
[Wed Feb 16 21:15:25 CST 2011]Pragma: no-cache
[Wed Feb 16 21:15:25 CST 2011]Cache-Control: no-cache, no-store, max-age=0
[Wed Feb 16 21:15:25 CST 2011]{"request":"/search.json?q=?é????","error":"oauth_signature=XMJW2PnNi1TuL1kSkiwCmBbSejA= oauth_signature_base_string=GET&http%3A%2F%2Fapi.t.163.com%2Fsearch.json&oauth_consumer_key%3DEJ0GpH9mtU584qtY%26oauth_nonce%3D1981498615%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1297862125%26oauth_token%3D3d5ec3c98e57d20c40c458bfe6999d66%26oauth_version%3D1.0 oauth_problem=signature_invalid oauth_signature_method=HMAC-SHA1","error_code":"401"}
at t4j.http.HttpClient.httpRequest(HttpClient.java:514)
at t4j.http.HttpClient.get(HttpClient.java:497)
at t4j.TBlog.get(TBlog.java:949)
at t4j.TBlog.searchStatus(TBlog.java:773)
at _jsp._callback__jsp._jspService(_callback__jsp.java:46)
at com.caucho.jsp.JavaPage.service(JavaPage.java:61)
at com.caucho.jsp.Page.pageservice(Page.java:578)
at com.caucho.server.dispatch.PageFilterChain.doFilter(PageFilterChain.java:195)
at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:187)
at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:265)
at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:273)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:682)
at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
at java.lang.Thread.run(Thread.java:662)
上面的提示是你的认证没通过,其实完全不是这么回事,你只要把那个搜索语句改一下就得了:
List<Status> list = tblog.searchStatus(java.net.URLEncoder.encode("情人节","UTF-8"));
到此,真的就都OK了,真的希望网易做事能彻底些,这些事其实如果有个好的例子,我也不用摸黑搞了两天。
完整的开发程序的地址在这里:http://dl.dbank.com/c035vpc4d4
我的微博
http://t.sina.com.cn/1401900445