1、点击我们网站的社交登录按钮
2、跳转到微博授权登录页
3、当我们输入完账号密码后,会跳转到我们回调地址
我们的回调地址是一个controller中的接口,目的是为了避免微博给我们返回的code直接暴露在页面上
我们的接口如下:
/**
* 社交登录成功的回调
* @param code
* @return
* @throws Exception
*/
@GetMapping("/oauth2.0/weibo/success")
public String weibo(@RequestParam("code") String code) throws Exception {
// TODO: 2023/2/11 微博开放平台认证完毕后,下面参数改成自己的
Map<String, String> map = new HashMap<>();
map.put("client_id","2077705774");
map.put("client_secret","40af02bd1c7e435ba6a6e9cd3bf799fd");
map.put("grant_type","authorization_code");
map.put("redirect_uri","http://auth.gulimall.com/oauth2.0/weibo/success");
map.put("code",code);
//1、根据code获取access_token(HttpUtils是自己写的发送请求的工具类)
HttpResponse response = HttpUtils.doPost("https://api.weibo.com", "/oauth2/access_token", "post", new HashMap<>(), map, new HashMap<>());
//2、处理
if (response.getStatusLine().getStatusCode()==200){//获取accessToken成功
//获取到了accessToken
String json = EntityUtils.toString(response.getEntity());//EntityUtils是org.apache.http.util下的一个工具类,可以将HttpEntity的实体类转化为字符串
SocialUser socialUser = JSON.parseObject(json, SocialUser.class);
//知道当前是哪个社交用户
//(1)当前用户如果第一次进网站,自动注册进来(为当前社交用户生成一个会员信息账号,以后这个社交账号就对应指定的会员)
//登录或者注册这个社交用户
R oauthLogin = memberFeignService.oauthLogin(socialUser);
if (oauthLogin.getCode()==0){
MemberRespVo memberRespVo = oauthLogin.getData("data", new TypeReference<MemberRespVo>() {});
System.out.println("社交登录成功::" + memberRespVo.toString());
//登录成功就跳回首页
return "redirect:http://gulimall.com";
}else {
//登录失败
return "redirect:http://auth.gulimall.com/login.html";
}
}else {
//获取access_token失败
return "redirect:http://auth.gulimall.com/login.html";
}
}
首先根据code获取access_token,如果获取成功,直接通过JSON将微博给我们返回的json数据转为实体类,通过这个实体类我们可以获得access_token,uid(用户的唯一标识)、access_token过期时间。
然后我们通过调用远程服务(Member),查询该用户是否是第一次登录(通过查询数据库有没有该uid),如果是第一次登录我们还要为他注册。memberService接口如下:
(这是远程服务暴露的请求地址)
(这是接口的具体实现)
//社交登录(登录和注册一体)
@Override
public MemberEntity login(SocialUser socialUser) throws Exception {
String uid = socialUser.getUid();
//判断当前社交用户是否已经登陆过系统
MemberDao memberDao = this.baseMapper;
MemberEntity memberEntity = memberDao.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", uid));
if (memberEntity!=null){
//这个用户已经注册过
/**
* 注意我们的数据库表的设计要加上uid、令牌、令牌过期时间这三个字段
*/
memberEntity.setAccessToken(socialUser.getAccess_token());//更新令牌
memberEntity.setExpiresIn(socialUser.getExpires_in());//更新令牌过期时间
memberDao.updateById(memberEntity);//更新数据库表
return memberEntity;
} else {
//2、没有查到当前社交用户对应的记录我们就需要注册一个
MemberEntity register = new MemberEntity();
//其实查询出现异常,也不影响我们注册(这些查询的信息无关紧要)
try {
//3、查询当前社交用户的社交账号信息(昵称、性别等)
Map<String,String> query = new HashMap<>();
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");
String gender = jsonObject.getString("gender");
register.setNickname(name);
register.setGender("m".equals(gender) ? 1 : 0);
//其他信息都可以从结果中获取
}
}catch (Exception e){}
register.setSocialUid(socialUser.getUid());
register.setAccessToken(socialUser.getAccess_token());
register.setExpiresIn(socialUser.getExpires_in());
//把用户信息插入到数据库中
memberDao.insert(register);
return register;
}
}
然后根据调用远程服务返回的结果,判断是否登录成功,然后跳转到相应的页面即可;
标签:code,登录,86,socialUser,---,token,new,社交 From: https://www.cnblogs.com/morehair/p/17112538.html