以微博开发平台为例,使用社交账号登录网站
一、参考文档
OAuth2.0授权认证
二、原理:
①概念原理:

②实际操作时的原理图:

三、以POSTMAN为例对链接进行测试
① 引导需要授权的用户到如下地址(在前端页面链接设置一下URL):
URL:
https://api.weibo.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI
其中
YOUR_CLIENT_ID、YOUR_REGISTERED_REDIRECT_URI分别代表下图中APP KEY和授权回调页:
② 运行页面登录后,页面跳转至 YOUR_REGISTERED_REDIRECT_URI/?code=CODE,获取CODE,利用postman测试以下链接:
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
其中YOUR_CLIENT_ID、YOUR_CLIENT_SECRET分别代表APP KEY和APP Secret,YOUR_REGISTERED_REDIRECT_URI代表授权回调页,code则为CODE授权令牌:

四、具体代码编写
①OAuth2Controller类的编写
@Controller public class OAuth2Controller { @Autowired MemberFeignSerivce memberFeignSerivce; @GetMapping( "/oauth2.0/weibo/success") public String weibo(@RequestParam("code") String code) throws Exception { //1、根据code换取accessToken Map<String,String> map = new HashMap<>(); map.put("client_id","21*********6"); map.put("client_secret","65ae****************e30a"); map.put("grant_type","authorization_code"); map.put("redirect_uri","http://auth.gulimall.com/oauth2.0/weibo/success"); map.put("code",code); HttpResponse response = HttpUtils.doPost("https://api.weibo.com", "/oauth2/access_token", "post", new HashMap<String, String>(), new HashMap<String, String>(), map); //2、处理微博登陆成功的回调 System.out.println(response.getStatusLine().getStatusCode()); if (response.getStatusLine().getStatusCode()==200){ //将返回的json数据变成对象 String json = EntityUtils.toString(response.getEntity()); System.out.println("返回json数据:"+json); SocialUser socialUser = JSON.parseObject(json, SocialUser.class); //如果当前用户是第一次登录则自动注册为本网站用户(为当前社交用户生成一个信息账号,以后社交账号对应指定会员) //登录或注册这个账户 R oauthlogin = memberFeignSerivce.oauthlogin(socialUser); if (oauthlogin.getCode()==0){ MemberResVo data = oauthlogin.getData("data", new TypeReference<MemberResVo>() { }); System.out.println("登陆成功:"+ data.toString()); return "redirect:http://gulimall.com"; }else { return "redirect:http://auth.gulimall.com/login.html"; } }else { return "redirect:http://auth.gulimall.com/login.html"; } } }
②使用远程调用功能
@FeignClient("gulimall-member")
public interface MemberFeignSerivce {
@PostMapping("/member/member/oauth2/login")
public R oauthlogin(@RequestBody SocialUser socialUser);
}
@RestController @RequestMapping("member/member") public class MemberController { @Autowired private MemberService memberService; @PostMapping("/oauth2/login") public R oauthlogin(@RequestBody SocialUser socialUser) throws Exception { MemberEntity memberEntity = memberService.login(socialUser); if (memberEntity != null) { return R.ok().setData(memberEntity); } else { return R.error(BizCodeEnume.LOGIN_PASSWORD_INVAILD_EXCEPTION.getCode(),BizCodeEnume.LOGIN_PASSWORD_INVAILD_EXCEPTION.getMsg()); } } }
③MemberService接口编写和实现类
public interface MemberService extends IService<MemberEntity> { MemberEntity login(SocialUser socialUser) throws Exception; }
@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {
@Resource
MemberLevelDao memberLevelDao;
@Override
public MemberEntity login(SocialUser socialUser) throws Exception{
//登录和合并逻辑
String uid = socialUser.getUid();
//1、判断当前社交用户是否已经登陆过
MemberDao baseMapper = this.baseMapper;
//查找当前社区用户的账号uid
MemberEntity memberEntity = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", uid));
//则表明已注册过
if (memberEntity != null) {
MemberEntity update = new MemberEntity();
update.setId(memberEntity.getId());
update.setAccessToken(socialUser.getAccess_token());
update.setExpiresIn(socialUser.getExpires_in());
//仅仅是更新本次的令牌号码和过期时间
baseMapper.updateById(update);
//返回最新的本次的令牌号码和过期时间
memberEntity.setAccessToken(socialUser.getAccess_token());
memberEntity.setExpiresIn(socialUser.getExpires_in());
return memberEntity;
} else {
//2、没查到当前用户,则需要注册
MemberEntity regist = new MemberEntity();
try {
//查询当前社交用户的社交信息资料
HashMap<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");
//......
regist.setNickname(name);
regist.setGender("m".equals(gender) ? 1 : 0);
//.......
}
} catch (Exception e) {
e.printStackTrace();
}
regist.setSocialUid(socialUser.getUid());
regist.setAccessToken(socialUser.getAccess_token());
regist.setExpiresIn(socialUser.getExpires_in());
//插入数据库
baseMapper.insert(regist);
return regist;
}
}
}
③所需要的实体类
@ToString @Data public class MemberResVo { private Long id; /** * 会员等级id */ private Long levelId; /** * 用户名 */ private String username; /** * 密码 */ private String password; /** * 昵称 */ private String nickname; /** * 手机号码 */ private String mobile; /** * 邮箱 */ private String email; /** * 头像 */ private String header; /** * 性别 */ private Integer gender; /** * 生日 */ private Date birth; /** * 所在城市 */ private String city; /** * 职业 */ private String job; /** * 个性签名 */ private String sign; /** * 用户来源 */ private Integer sourceType; /** * 积分 */ private Integer integration; /** * 成长值 */ private Integer growth; /** * 启用状态 */ private Integer status; /** * 注册时间 */ private Date createTime; /** * accesstoken码 */ private String accessToken; /** * 过期时间 */ private long expiresIn; /** * 社区账户的id */ private String socialUid; }
@Data @TableName("ums_member") public class MemberEntity implements Serializable { private static final long serialVersionUID = 1L; /** * id */ @TableId private Long id; /** * 会员等级id */ private Long levelId; /** * 用户名 */ private String username; /** * 密码 */ private String password; /** * 昵称 */ private String nickname; /** * 手机号码 */ private String mobile; /** * 邮箱 */ private String email; /** * 头像 */ private String header; /** * 性别 */ private Integer gender; /** * 生日 */ private Date birth; /** * 所在城市 */ private String city; /** * 职业 */ private String job; /** * 个性签名 */ private String sign; /** * 用户来源 */ private Integer sourceType; /** * 积分 */ private Integer integration; /** * 成长值 */ private Integer growth; /** * 启用状态 */ private Integer status; /** * 注册时间 */ private Date createTime; /** * accesstoken码 */ private String accessToken; /** * 过期时间 */ private long expiresIn; /** * 社区账户的id */ private String socialUid; }
五、整个工作流程


浙公网安备 33010602011771号