OAuth2 - 第三方登录之新浪微博登录

之前写过一篇OAuth2 - 第三方登录之微信登录,但是微信的开放平台的资质需要有公司/企业才能注册。如果是个人的话,可以使用其他个人开发者就可以使用的。比如QQ、新浪微博。
QQ的话,需要审核之后才能使用,需要手持身份证照。而微博的话,在开发期间使用无需审核就可以使用。

微博开放平台 - 创建应用

微博 - 开放平台地址

1、登录之后选择网站接入

在这里插入图片描述

2、完善个人开发者信息

在这里插入图片描述

3、创建应用

创建自己要使用微博登录功能的应用。
在这里插入图片描述

4、设置回调地址

即登录授权成功之后的回调地址
在这里插入图片描述

5、添加测试用户

测试用户即微博用户,输入微博昵称即可。
在这里插入图片描述
在开发阶段无需审核,设置完上述内容即可使用。
在这里插入图片描述

微博开放平台 - 登录流程体验

1、开发文档,选择OAuth2.0,并找到Web网站的授权

微博开发平台 - 开发文档
在这里插入图片描述
在这里插入图片描述

2、根据文档进行操作
①引导需要授权的用户到如下地址:
https://api.weibo.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI

该地址中有两个替换的参数

client_id:即App Key

在这里插入图片描述

redirect_uri:即回调地址

在这里插入图片描述
访问该地址即跳转到微博登录页面:
在这里插入图片描述

②如果用户同意授权,页面跳转至YOUR_REGISTERED_REDIRECT_URI?code=CODE

YOUR_REGISTERED_REDIRECT_URI 即是回调地址。
在这里插入图片描述

③换取Access Token

通过返回的code码去换取Access Token,只有获取了Token才能为所欲为。

https://api.weibo.com/oauth2/access_token?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=authorization_code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=CODE

这是一个POST请求,在体验这个流程的时候可以通过postman来进行操作。
该地址中有四个替换的参数:

client_id:即App Key
client_secret:即App Secret
redirect_uri:回调地址
code:登录成功之后,地址栏返回的code值

在这里插入图片描述
换取成功返回的JSON结果:
在这里插入图片描述

④使用获得的Access Token调用API

获取到token之后,就可以凭此调用其他接口(有权限的接口)。
在这里插入图片描述
测试 - 获取用户信息:
在这里插入图片描述

Java中的使用流程

在这里插入图片描述

1、引导到登录页面
https://api.weibo.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI
2、回调地址

登录授权成功之后,会跳转到回调地址,并且附带一个code。
因为client_secret,也就是AppSecret不能外泄,所以需要在Java代码内部进行操作。
创建一个Controller作为回调跳转的地址,并且接受code,使用code去交换access_token,其中access_token也是不能外泄的
因为在Java代码中需要发送请求,所以需要一个HttpsUtils工具类

/**
* HttpUtils请从
* https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
* 或者直接下载:
* http://code.fegine.com/HttpUtils.zip
*
* 下载相应的依赖请参照
* https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
* 相关jar包(非pom)直接下载:
* http://code.fegine.com/aliyun-jar.zip
*/
3、模拟微博登录的方法 - 回调方法
/**
 * 微博登录回调方法
 * @param code 回调带回来的code值
 * @return 跳转的地址
 */
@GetMapping("/oauth2.0/weibo/success")
public String weiboLogin(@RequestParam("code") String code) throw Exception {
    // 头信息不能为null
    Map<String, String> header = new HashMap<>();
    // query不能为null
    Map<String, String> query = new HashMap<>();
    // 这个Map就是body参数体
    Map<String, String> map = new HashMap<>();
    // client_id,即App Key
    map.put("client_id", WeiboConstant.WEIBO_CLIENT_ID);
    // client_secret,即App Secret
    map.put("client_secret",WeiboConstant.WEIBO_CLIENT_SECRET);
    // 固定的grant_type - authorization_code
    map.put("grant_type",WeiboConstant.WEBIBO_GRANT_TYPE);
    // 回调地址
    map.put("redirect_uri",WeiboConstant.WEIBO_REDIRECT_URI);
    // code码
    map.put("code",code);
    // 发送POST请求 - 获取access_token
    HttpResponse response = HttpUtils.doPost("https://api.weibo.com", "/oauth2/access_token", "post", header, query, map);
    // 拿到access_token就可以为所欲为了 - 前提是有对应调用接口的权限
    if(response.getStatusLine().getStatusCode() == 200){   // 请求状态为200,表示成功
    	// 通过getEntity方法可以得到如下格式的JSON字符串
    	/*
    		{
    		"access_token": "2.00gvBwvFEBF9VzcseAe2b7c8Jy47iB",
    		"remind_in": "157679999",
    		"expires_in": 157679999,
    		"uid": "5438845756",
    		"isRealName": "true"
    		}
    	*/
    	// 可以提前创建一个对应这个JSON的POJO类,我这里对应的POJO类为SocialUser
    	String json = EntityUtils.toString(response.getEntity());
    	// 转换成对应的POJO类
    	SocialUser socialUser = JSON.parseObject(json, SocialUser.class);
    	/**
    	 * 此时可以写一个业务去判断登录的用户是否已经存在
    	 * 一般就通过uid去查询,如果能查询出来对应的用户对象,直接返回即可
    	 * 当然在返回之前还需要更新数据库中对应的access_token、expires_in字段(令牌和令牌过期时间)
    	 *
    	 * 如果数据库中不存在,则需要存入数据库之后返回
    	 */
    	 
    	 // 将这段逻辑封装成loginService中的一个方法
    	 User user = loginService.login(socialUser);
    	 // 成功返回到主页,至于user的信息,可以存储在session中....
    	 return "";
    }else{
    	// 失败返回登录页面,并提示.....
    	return "";
    }
}


// loginService中的login方法
/**
 * 登录和注册合并逻辑
 * @param socialUser 微博请求返回的对象
 * @return User则为系统中真实的对象,即含有昵称、个性签名等的对象
 */
public User login(SocialUser socialUser) throws Exception{
	// 获取uid
	String uid = socialUser.getUid();
	// Dao - 根据uid查询User
	User user = userDao.selectUserByUid(uid);
	// 要返回的User对象 - userRe
	User userRe = new User();
	if(user != null){  // user存在
		// 替换属性 - 将查询出来的user所有属性复制到userRe中
		BeanUtils.copyProperties(user,userRe);
		// 设置最新的AccessToken和过期时间
		userRe.setAccessToken(socialUser.getAccessToken());
		userRe.setExpiresIn(socialUser.getExpiresIn);
		// 更新
		userDao.updateById(userRe);
	}else{ // user不存在,第一次登陆本系统
		// 查询微博社交账号的信息
		Map<String, String> query = new HashMap<>();
		// 根据AccessToken和Uid查询
		query.put("access_token",socialUser.getAccess_token());
        query.put("uid",socialUser.getUid());
		HttpResponse response = HttpUtils.doGet("https://api.weibo.com", "/2/users/show.json", "get", new HashMap<String, String>(), query);
		if (response.getStatusLine().getStatusCode() == 200){
			// 查询成功
			String json = EntityUtils.toString(response.getEntity());
			JSONObject jsonObject = JSON.parseObject(json);
			// 昵称
			String name = jsonObject.getString("name");
			userRe.setNickname(name);
			// ....更多的信息,如头像地址、个性签名等,一一设置进去
		}
		userRe.setSocialUid(socialUser.getUid());
        userRe.setAccessToken(socialUser.getAccessToken());
        userRe.setExpiresIn(socialUser.getExpiresIn());
		// 插入到数据库中
		userDao.insert(userRe);
	}
	// 返回userRe
	return userRe;
}
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页