网站接入第三方平台登录--QQ篇
https://blog.csdn.net/qq_34333537/article/details/112802902
网站接入第三方平台登录--微信篇
目录
准备工作
注册开放平台并新建应用
在新建应用的的信息中,如下信息需要保证正确,不然在后续请求中会出现重定向地址不正确错误。
调试应该在上面回调地址上进行调试
获取App Key和App Secret
如上图
业务分析
- 引导用户进行授权
- 拿到授权code后去微博换取token
- 如果需要其它操作则token调用相应接口
我的业务逻辑
注意:官方并不推荐使用uid判断登录,我这里求简只是需要是否绑定了账户
实战开发
环境
前端:VUE
后端:SpringBoot
代码
官方开发文档,参考Web网站部分,这是没用JS SDK是因为在VUE中无法解析该SDK的按钮组件
放置登录按钮
在合适的地方放入引导用户登录的元素,按钮之类的没有具体要求
<el-image style="width: 16px; height: 16px; margin-left: 10px;" @click="weiboClick" :src="require('@/assets/icon/weibo_16x16.png')" fit="fit"></el-image>
...
// 微博图标点击按钮
weiboClick() {
window.location.href = "https://api.weibo.com/oauth2/authorize?client_id=你的appKey&redirect_uri=你的回调地址";
}
用户点击该链接后会打开微博授权界面
进行登录后会自动重定向到回调地址,并且在url中拼接授权成功的code
因为vue的路由默认是带hash的,这样是无法取到url中的参数,这里求简直接通过字符串的方式获取参数
// 截取url参数
getSearchString(key, search) {
let str = search;
str = str.substring(1, str.length);
let arr = str.split('&');
let obj = {};
for (let i = 0; i < arr.length; i++) {
let tmp_arr = arr[i].split("=");
obj[decodeURIComponent(tmp_arr[0])] = decodeURIComponent(tmp_arr[1]);
}
return obj[key];
}
携带code去后台换取微博token进行登录
在created钩子中获取code,并通过code去后端进行登录的判断(后端接收到code去微博接口换取token、uid等信息,在库中进行比较判断是否是本系统用户,是就予以通过,不是返回提示进行绑定)
created() {
let code = this.getSearchString("code",window.location.search)
if (code) {
// 获取微博token
user.getWeiBoToken({code: code}).then(res => {
this.afterLogin(res);
})
}
}
// 登录请求后的逻辑处理
afterLogin(res) {
if (res.code === 200) {
let {data} =res
this.set_token(data.token)
this.set_userInfo(data)
this.$message.success(res.msg);
this.$router.push('/dashboard');
} else if (res.code === 201) {
// 将uid赋值到登录的参数对象中用以登录绑定
this.param.weiboId = res.data;
this.$message.error("你的微博尚未绑定账户,请进行密码登录进行绑定!");
} else {
this.$message.error(res.msg);
}
}
后端接口
官方换取token文档
/**
* 微博token接口返回对象
* @ClassName WeiBo
* @Author snow
* @Date 2021/1/21 17:58
*/
@Getter
@Setter
public class WeiBoToken {
private String access_token;
private String remind_in;
private String expires_in;
private String uid;
private String isRealName;
}
/**
* 微博登录
* @param code 微博回调获取的code
* @return 登录成功、失败、需要绑定账号
*/
@GetMapping("/getWeiBoToken")
public JSONObject getWeiBoToken(String code) {
if (DataOperateUtil.isNull(code)) {
return fail("缺少code");
}
RestTemplate restTemplate = new RestTemplate();
MultiValueMap<String, String> header = new LinkedMultiValueMap<>();
header.put(HttpHeaders.CONTENT_TYPE, Collections.singletonList(MediaType.APPLICATION_JSON_VALUE));
header.put(HttpHeaders.ACCEPT, Collections.singletonList(MediaType.APPLICATION_JSON_VALUE));
HttpEntity<JSONObject> request = new HttpEntity<>(new JSONObject(), header);
String url = "https://api.weibo.com/oauth2/access_token?client_id=1224469031&client_secret=fa36b19aa07f3362623adf702bf70837&grant_type=authorization_code&redirect_uri=http://sybm.jxsycm.com&code=" + code;
try {
// 请求微博换取token、uid等信息
ResponseEntity<String> exchangeResult = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
System.out.println(exchangeResult);
WeiBoToken weiBoToken = JSON.toJavaObject(JSONObject.parseObject(exchangeResult.getBody()), WeiBoToken.class);
// 判断该微博id是否在库中关联了用户
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("weibo_id", weiBoToken.getUid());
queryWrapper.ne("`status`", 0);
SysUser sysUser = sysUserService.getOne(queryWrapper);
if (sysUser == null) {
// 没有绑定账号
return success(201, weiBoToken.getUid());
} else {
// 已获取到用户信息,进行登录(token处理、日志记录等操作)
return loginService(sysUser);
}
} catch (HttpClientErrorException e) {
e.printStackTrace();
}
return fail("请求微博token异常");
}
如果是没有绑定账户,则在前端进行账号密码登录,登录方法中判断uid是否有值,如果有就进行登录绑定操作
submitForm() {
this.$refs.login.validate(valid => {
if (valid) {
if (this.param.weiboId) {
// 进行登录绑定
user.weiboBindAccount(this.param).then(res=>{
this.afterLogin(res)
})
} else {
user.login(this.param).then(res=>{
this.afterLogin(res)
})
}
} else {
this.$message.error('请输入账号和密码');
console.log('error submit!!');
return false;
}
});
}
登录绑定接口
/**
* 微博绑定账号
* @param param username、password、微博id
* @return 绑定后进行登录
*/
@PostMapping("/weiboBindAccount")
public JSONObject weiboBindAccount(@RequestBody SysUser param) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(param.getUsername(), param.getPassword());
try {
...
SysUser sysUser = ...
...
// 登录成功
// 绑定weiboId到账户
sysUser.setWeiboId(param.getWeiboId());
sysUserService.updateById(sysUser);
return loginService(sysUser);
} catch (AuthenticationException e) {
LogUtil.addLogToFile(param.toString(), "登录异常", "", LogUtil.LogLevel.error, e.getMessage());
return fail("账号或密码错误");
}
}
以上,微博登录完成!