86、商城业务---认证服务---社交登陆步骤

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;
        }
    }

然后根据调用远程服务返回的结果,判断是否登录成功,然后跳转到相应的页面即可;

posted @ 2023-02-11 20:48  不是孩子了  阅读(106)  评论(0)    收藏  举报