DefaultApi20前篇文章说了如何使用基本的http api来调用新浪微博的应用,而在登陆这方面,新浪使用的是基本oauth2.0的授权应用,而其它如网易,腾讯则是使用基本1.0的调用,那么这两种应用都是基本oauth授权的应用,肯定有相应统一的开发技术了,那就是scribe。
关于scribe,可以访问其官方网站:https://github.com/fernandezpablo85/scribe-java,当然使用maven的话,可以使用以下的引用将其引用到项目中来:
<dependency> <groupId>org.scribe</groupId> <artifactId>scribe</artifactId> <version>1.3.0</version> </dependency>
scribe支持oauth1.0a以及oauth2.0两个版本的授权应用。关于1.0和2.0的区别可以google进行查看,总的来说2.0是要比1.0要好些,应用也简单些。但每个提供商所支持的版本也不尽相同,所以本文分别演示两个版本的应用。
由于腾讯和网易所支持的版本均为1.0a,而新浪为2.0,所以本文仅给出参考代码,具体的代码,都差不多,无非就是根据不同的提供商的请求地址和参数进行修改的变化而已,主要的代码还是不变的。
备注:由于腾讯和网易在不给call_back参数的时候,需要设置为null,而不是标准中的oob,此处特地注明。
在scribe应用中,已经提供了国内主要微博和社区的oauth service api,其中有人人,新浪(仅为1.0a),腾讯和网易,所以本文也不需要额外再写了(当然要写的话还是很简单的)。这里要感谢Artorius,他的文章为:http://artori.us/java-oauth-lib-scribe-java-start-supporting-weibo。
oauth1.0a->腾讯,网易微博
scribe已经提供了腾讯和网易的实现,其中腾讯为QWeiboApi,网易为NeteaseWeibooApi。首先是如何获得access_token,关于获取这个token,首先要经过以下三步:
- 获取未授权的request_token
- 使用request_token将用户引导至提供商的授权界面,这里用户要提供用户密码信息并授权应用访问,并返回一个授权码,称之为verifier
- 使用request_token和virifier一起请求access_token
以下这张图可以更详细的理解一下(引自腾讯api):
那么这三个步骤使用Scribe就很好地理解了,以下为详细的代码:
OAuthService service = new ServiceBuilder().provider(NeteaseWeibooApi.class).apiKey("你的api Key") .apiSecret("你的api 授权私钥").callback("回调网址") .signatureType(SignatureType.QueryString).build(); Token token = service.getRequestToken(); //第一步:取得request_token String authUrl = service.getAuthorizationUrl(token); 第二步:将用户引导至提供商的授权界面 Desktop.getDesktop().browse(new URI(authUrl)); //第二步:让用户提供由提供商返回的授权verifier,这一步在实现中是手动地录入的 String verifyCode = new Scanner(System.in).nextLine(); //第三步:获取access_token,整个流程完毕 Token accessToken = service.getAccessToken(token, new Verifier(verifyCode));
那么取得access_token之后, 我们就可以使用它进行再一步调用了,如下就是一个如何access_token发腾讯微博的例子:
OAuthRequest addRequest = new OAuthRequest(Verb.POST, "http://open.t.qq.com/api/t/add"); //这下面的都是腾讯要求的参数 addRequest.addBodyParameter("format", "json"); addRequest.addBodyParameter("content", "我用java api发qq微博,你呢:)"); addRequest.addBodyParameter("clientip", "127.0.0.1"); addRequest.addBodyParameter("jing", ""); addRequest.addBodyParameter("wei", ""); addRequest.addBodyParameter("syncflag", "1"); //oauth1.0a需要一个参数签名信息,即oauth_signature service.signRequest(accessToken, addRequest); //发送请求 response = addRequest.send(); //取得返回值,可以进行下一步操作了,如解析数据,显示数据等 System.out.println(response.getBody());
oauth2.0->新浪微博
相比oauth1.0,oauth2.0的请求过程就相比简单了,主要就是两个步骤:
- 引导用户至授权界面,获取用户授权的verifier值
- 使用verifier获取到相应的access_token
以下是相应的参考代码:
OAuthService service = new ServiceBuilder().provider(SinaWeibo2Api.class).apiKey("应用key") .apiSecret("应用私钥").callback("回调网址") .signatureType(SignatureType.QueryString).build(); //获取授权引导界面,引导用户至授权界面 String authUrl = service.getAuthorizationUrl(null); Desktop.getDesktop().browse(new URI(authUrl)); //使用用户授权之后得到的verifier获取到access_token String verifyCode = new Scanner(System.in).nextLine(); Token accessToken = service.getAccessToken(null, new Verifier(verifyCode));
在以上的代码中,使用了一个SinaWeibo2Api的类,这在scribe中是没有的,它只提供了oauth1.0a的新浪实现,而最新的新浪api只提供了基本oauth2.0的api访问,所以我们需要自己提供一个相应的provider实现就可以了。这个provider的写法可以参考一下类DefaultApi20的子类,如FacebookApi的写法,下面是一个参考的实现(实践证明也确实可以用)
public class SinaWeibo2Api extends DefaultApi20{ private static final String AUTHORIZE_URL = "https://api.weibo.com/2/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code"; private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; @Override //这个是获取access_token的网址,需要在api中注明 public String getAccessTokenEndpoint() { return "https://api.weibo.com/2/oauth2/access_token?grant_type=authorization_code"; } @Override public String getAuthorizationUrl(OAuthConfig config){ ......这个直接copy其它实现 } @Override public AccessTokenExtractor getAccessTokenExtractor(){ return new JsonTokenExtractor(); } @Override //这个需要重写,因为默认实现是get,而新浪要求获取access_token之类,必须使用post请求 public Verb getAccessTokenVerb() { return Verb.POST; }
其它应用如使用代码发新浪微博,就与腾讯的代码一致了,这里就不再叙述。总的来说,使用scribe,不需要了解具体的http协议,且现有的各个提供商对标准的支持也更好了,根本不需要修改scribe的代码(当然处理call_back这儿有点问题)。即不需要更换api实现,只需要修改一下http请求地址和相应的参数,就可以直接使用代码访问另一个微博api了。相比使用官方提供的api实现,这个还是更方便一些,仅对于登陆这一环节而言,如何要使用这个进行通用类api访问,肯定要做更多的工作,当然这个也不是scribe所关注的。
转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/201201030001.html