游戏人生看别样风景

首页 » Java笔记 » 正文

新浪微博第三方登陆开发流程及常见问题

2017年02月11日 | 分类:Java笔记 | 作者:hucker | 评论:0条评论 | 浏览:1735

搞一个新浪微博第三方登陆费了我半天时间,现在把它的流程简单写一下,希望读者可以少走弯路。

大部分第三方登陆都是采用OAuth2.0接入方式(详见),我们所开发的网站项目可以使用两种方式进行接入:

(1)使用微博开放平台提供的SDK包,用户体验统一,只需要修改少量代码,不需要理解验证授权流程,需要快速接入微博登录的网站和移动应用可选用此方法。

(2)根据微博登录OAuth2.0协议,自主开发,此方法自定义程度较高,需要与现有系统进行整合的网站和移动应用可选用此方法。

我使用的是第二种接入方式,下面我们进入正题:

首先,我们需要进入到 http://open.weibo.com/ 并注册一个开发者账号:(这里注册和身份审核就不多介绍了)

第二步创建应用

 

点击微连接----->立即创建微连接

图片1.png

 

 选择 网页应用 并填写应用名称

图片2.png

 

填写应用信息

图片3.png 

注意上传图片必须按照要求尤其是图片大小,(可以使用可以看到像素大小的截图工具随便截取,我使用的是QQ截图

 

填写完成后提交审核。

 

第三步:设置授权回调页

选择我的应用---->应用信息---->高级信息

图片4.png 

填写回调页时,本机测试地址不可写成localhost 可以使用 127.0.0.1

接下来我们就可以使用微博提供的唯一性idsecret安全码进行接入测试了

 

参考OAuth2.0文档:

http://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E

 

 

接口

说明

OAuth2/authorize

请求用户授权Token

OAuth2/access_token

获取授权过的Access Token

OAuth2/get_token_info

授权信息查询接口

OAuth2/revokeoauth2

授权回收接口

OAuth2/get_oauth2_token

OAuth1.0的Access Token更换至OAuth2.0的Access Token


我们先来分析一下思路:

首先我们点击微博登陆按钮,跳转到微博登陆授权页面,用户登陆后会跳转到我们网站的回调地址。并发送给我们一个code随机码。这样第一次握手通信完成。

然后再将接收到的code随机码和之前注册的唯一性id和安全码发送给新浪微博,然后它会给我们返回给一个token令牌,令牌中包含了第三方账号的相关信息。第二次数据交互完成。

然后利用token再给微博发送第三次数据请求,获取用户信息(用户名,头像,性别,住址)。

很多第三方网站为了保护用户隐私,返回的信息都不是很全面,所以我们需要根据用户的绑定状态去进行下一步的跳转。

 

我们可以发现要实现三次通信要三个url地址,通过API可以发现Authorize access_toke 两个接口正好对应我们的前两次通信,第三次通信,可以在微博API--->用户中找到

图片5.png 

这里我第一次通信使用url请求,后两次使用HttpClient获取数据

需要注意的是Authorize可以使用get/post请求方式;access_toke只能使用potusers/show 只能使用get

 

第一次通信地址:

location.href = "https://api.weibo.com/oauth2/authorize?client_id=3234479019&response_type=code&redirect_uri=http://127.0.0.1:8080/ThirdLoginAPI/weiboLogin.do";


第二次第三次通信代码:

	/**
	 * 
	 * @author hucker
	 * @dateTime 2017年2月10日 下午22:32:37
	 * @return User
	 * @return
	 */
	public User weiboLogin(String code) {
		//定义第三方接口固定值
		String client_id = "3234479019";
		String client_secret = "3c05caf447b96a7e489973a38fa5q1c3";
		//定义返回地址字符串
		String redirect_uri = "http://127.0.0.1:8080/ThirdLoginAPI/weiboLogin.do";
		//拼接二次握手地址第二次使用access_token接口
		String url1 = "https://api.weibo.com/oauth2/access_token?client_id="+client_id+"&client_secret="+client_secret+"&grant_type=authorization_code&redirect_uri="+redirect_uri+"&code="+code;

		String content1 = "";
		try {
			CloseableHttpClient httpClient = HttpClients.createDefault();
			HttpPost httpPost = new HttpPost(url1);//access_token接口使用的是post方式
			
			//设置请求头
			httpPost.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			httpPost.addHeader("Accept-Encoding", "gzip, deflate, br");
			httpPost.addHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
			httpPost.addHeader("Connection", "keep-alive");
			httpPost.addHeader("Host", "api.weibo.com");
			httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0");
			
			//执行请求获得响应
			HttpResponse response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();  
			content1 = EntityUtils.toString(entity,"UTF-8"); //转码成字符串
		} catch (Exception e) {
			e.printStackTrace();
		}
		//将得到的字符串转化成json对象
		Map<String, Object> map1 = JSON.parseObject(content1,new TypeReference<Map<String, Object>>(){});
		
		//获取结果中参数access_token、uid(作为第三次握手的传送数据)
		String access_token = (String) map1.get("access_token");
		String uid = (String) map1.get("uid");
		
		//第三次通信地址第三次使用users/show.json接口 传递参数access_token、uid
		String url2 = "https://api.weibo.com/2/users/show.json?access_token="+access_token+"&uid="+uid;

		String content2 = "";
		
		try {
			CloseableHttpClient httpClient = HttpClients.createDefault();
			HttpGet httpGet = new HttpGet(url2);//第三次users/show.json接口还使用get

			//设置请求头
			httpGet.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			httpGet.addHeader("Accept-Encoding", "gzip, deflate, br");
			httpGet.addHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
			httpGet.addHeader("Connection", "keep-alive");
			httpGet.addHeader("Host", "api.weibo.com");
			httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0");
			
			HttpResponse response = httpClient.execute(httpGet);
			HttpEntity entity = response.getEntity();  
			content2 = EntityUtils.toString(entity,"UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		//将得到json字符串的值转化为map
		Map<String, Object> map2 = JSON.parseObject(content2,new TypeReference<Map<String, Object>>(){});
		String weiboid = (String) map2.get("idstr");
		
		//向数据库中查询是否存在百度id(存在直接获取user跳转成功,不存在则像数据库添加一条记录再跳转)
		User user = new User();
		user.setWeiboid(weiboid);
		User u = userMapper.findUserByWeiboid(user);
		if(u != null){
			return u;
		}else{
			String username = (String) map2.get("screen_name");
			String sex = (String) map2.get("gender");//性别,m:男、f:女、n:未知
			user.setUsername(username);
			user.setSex(sex);
			return user;
		}
	}





错误分析:

{"error":"HTTP METHOD is not suported for this request!","error_code":10021,"request":"/oauth2/access_token"}

通过code获取access_token获取tocken报HTTP方式错误,只需把请求方式改为post即可解决。


{"error":"invalid_grant","error_code":21325,"request":"/oauth2/access_token","error_uri":"/oauth2/access_token","error_description":"invalid authorization code:6d879b0a49fed0e603b6fa4cee68dd80"}

通过access_token获取uid时报错无权限错误




发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

«   2024年3月   »
123
45678910
11121314151617
18192021222324
25262728293031
网站分类
标签列表
最近发表
最新留言
网站收藏
    RainbowSoft Studio Z-BlogRainbowSoft Studio Z-Blog订阅本站的 RSS 2.0 新闻聚合html5创意