java第三方登录总结

一、网页端扫二维码绑定第三方的登录
在这里插入图片描述
1、发起微信授权登录请求

  @Override
    public ResponseData userLoginByThirdPlatformWeb(ThirdPlatformWebReqDTO thirdPlatformWebReqDTO, HttpServletRequest request) {
        log.info("第三方web登录外部接口请求参数,{}", thirdPlatformWebReqDTO);
        String referer = request.getHeader("Referer");
        Integer platform = thirdPlatformWebReqDTO.getPlatform();
        Integer sign = thirdPlatformWebReqDTO.getSign();
        try {
            if (StringUtils.isNotBlank(referer)) {
                referer = URLEncoder.encode(referer, "UTF-8");
            }
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
            return new ResponseData<>(LoginRegisterResultCode.FAILY);
        }
        log.debug("referer=========================>:{}", referer);
        String redirectCallback = "";
        String redirect = "";
        boolean isWap = WebUtil.checkClientIsMobile(request);
        if (Constant.QQ_PLATFROM.equals(platform.toString())) {
            //配置项目的回调地址和所带参数
            redirectCallback = Constant.HTTP_QQ_DOMAIN_URL + "?referer=" + referer + "&platform=" + platform + "&sign=" + sign;
            redirect = QQUtil.getAuthorizationUrlJump(isWap, redirectCallback, "test");
        } else {
            //配置项目的回调地址和所带参数
            redirectCallback = Constant.HTTP_WX_DOMAIN_URL + "?referer=" + referer + "&platform=" + platform + "&sign=" + sign;
            redirect = WxUtil.getAuthorizationUrlJump(redirectCallback, "test");
        }
        ReturnUrlRespDTO returnUrl = new ReturnUrlRespDTO();
        returnUrl.setUrl(redirect);
        log.info("第三方web登录接口返回参数,{}", returnUrl);
        return new ResponseData(LoginRegisterResultCode.SUCCESS, returnUrl);
    }

QQUtil.getAuthorizationUrlJump()函数

    public static String getAuthorizationUrlJump(boolean isWap, String redirect_uri, String state) {
        isWap = false;
        if (StringUtils.isNotBlank(redirect_uri)) {
            try {
                redirect_uri = URLEncoder.encode(redirect_uri, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                logger.error("------------QQ2.0----getAuthorizationCode URLEncoder失败:" + redirect_uri, e);
            }
        }
        String display = isWap ? "mobile" : "pc";
        String requestUrl = "https://graph.qq.com/oauth2.0/authorize?";
        requestUrl += "response_type=code&client_id=" + appid + "&redirect_uri=" + redirect_uri + "&state=" + state + "&scope=" + scope + "&display=" + display;
        return requestUrl;
    }

WxUtil.getAuthorizationUrlJump()函数

    // 授权跳转地址
    public static String getAuthorizationUrlJump(String redirect_callback, String state) {
        if (StringUtils.isNotBlank(redirect_callback)) {
            try {
                redirect_callback = URLEncoder.encode(redirect_callback, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                logger.error("---------WeixinUtil.getAuthorizationUrlJump() URLEncoder失败:" + redirect_callback, e);
            }
        }
        String requestUrl = "https://open.weixin.qq.com/connect/qrconnect?";
        requestUrl += "appid=" + weixin_AppID + "&redirect_uri=" + redirect_callback + "&response_type=code&scope=snsapi_login&state=" + state + "#wechat_redirect";
        return requestUrl;
    }

2、重定向到我们提供给腾讯回调地址并且给我们带过来code以及state参数,我们拿着临时凭证(code)去获取accessToken以及用户信息:

@Override
    public String thirdLoginWebCallBack(HttpServletRequest request) {
        String sign = request.getParameter("sign");
        String platform = request.getParameter("platform");
        // 第三方拼接好的参数code
        String authorizationCode = request.getParameter("code");
        String unionid = "";
        String phone = "";
        String userType = "";
        String userName = "";
        Integer isOrgUser = 0;
        Integer hasOrgPackage = 0;
        Integer isMonthPackageForLeave = 0;
        String mobileArea = "";
        String needRemid = "";
        String redirectCallback = "";
        //获取QQ或微信的unionid
        boolean isWap = WebUtil.checkClientIsMobile(request);
        if (Constant.QQ_PLATFROM.equals(platform)) {
            redirectCallback = Constant.HTTP_QQ_DOMAIN_URL;
            String accessToken = QQUtil.getAccessToken(isWap, authorizationCode, redirectCallback);
            unionid = QQUtil.getUnionid(isWap, accessToken);
            log.info("unionid=========================>:{}", unionid);
        } else {
            redirectCallback = Constant.HTTP_WX_DOMAIN_URL;
            JSONObject jsonObj = WxUtil.getUnionid4login(authorizationCode, redirectCallback);
            unionid = jsonObj.getString("unionid");
            log.info("unionid=========================>:{}", unionid);
        }
        //进行业务逻辑的操作
        TUserinfo userInfo = userInfoMapper.getUserInfoByUnionId(unionid, Integer.parseInt(platform));
        Integer userId = userInfo.getUserId();
        RedisUtil.saveUnionid(platform, authorizationCode, unionid);
        //通过unionid查询是否绑定
        //已绑定,跳转至学习大厅页面
        if (userInfo != null && unionid != null) {
           } else {
            //已注册未绑定,来源是登录后 个人中心-修改个人资料 跳转至已有界面未绑定页面(能登陆证明是老用户)
            if ("1".equals(sign)) {
                return Constant.TALK_SERVER_ADDRESS + "/student/login?routerBtn=thirdWithAccount&phone=" + phone + "&unionid=" + unionid + "&type=" + platform + "&sign=" + sign;
            }
            //未注册未绑定,来源是未登录的学生端首页 跳转至第三方注册页面(因为未登录状态无法判断用户为新的还是老用户,统一跳到第三方注册页面)
            else {
                return Constant.TALK_SERVER_ADDRESS + "/student/login?routerBtn=third";
            }
        }
    }

返回的链接,在controller层用重定向实现跳转 response.sendRedirect(refererUrl);

QQUtil.getAccessToken()函数

  /**
     * 获取Access Token
     *
     * @param authorization_code 授权第一步获得的authorization_code
     * @param redirect_uri       回调地址和初次请求的回调地址保持一致
     */
    public static String getAccessToken(boolean isWap, String authorization_code, String redirect_uri) {
        isWap = false;
        if (StringUtils.isBlank(authorization_code)) {
            logger.error("authorization_code不能为空!");
            return null;
        }
        String accessToken = "";
        String requestUrl = "https://graph.qq.com/oauth2.0/token?";
        if (isWap) {
            requestUrl = "https://graph.z.qq.com/moc2/token?";
        }
        requestUrl += "grant_type=authorization_code&client_id=" + appid + "&client_secret=" + appkey + "&code=" + authorization_code + "&redirect_uri=" + redirect_uri;
        String resultStr = httpGet(requestUrl);

        boolean success = StringUtils.isNotBlank(resultStr) && resultStr.contains("access_token");

        if (!success) {
            logger.error("requestUrl : " + requestUrl);
            logger.error("------------QQ2.0----getAccessToken error--backstr:" + resultStr);
            return accessToken;
        }

        String[] array = resultStr.split("&");
        String[] pair = array[0].split("=");
        accessToken = pair[1];
        return accessToken;
    }

WxUtil.getUnionid4login()函数

 // 获取Access Token / openid / unionid
    public static JSONObject getUnionid4login(String authorization_code, String referer) {
        String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?";
        requestUrl += "appid=" + weixin_AppID + "&secret=" + weixin_AppSecret + "&code=" + authorization_code + "&grant_type=authorization_code";

        String resultStr = WebUtil.httpGet(requestUrl, null, null, null);

        JSONObject jsonObj = JSONObject.parseObject(resultStr);
        return jsonObj;
    }

常见的报错处理
1、微信回调出错没有出现二维码(redirect_uri 参数错误)
在这里插入图片描述
解决方法正式服配置回调地址:
在这里插入图片描述
1、QQ回调出错登录后没有出现QQ头像(redirect_uri 参数错误)
在这里插入图片描述
解决方法正式服配置回调地址(QQ回调地址可以配置多个):
在这里插入图片描述

二、APP端直接绑定第三方的登录

 @Override
    public ResponseData<UserLoginRespDTO> userLoginByThirdPlatformAPP(UserLoginByThirdPlatformReqDTO userLoginByThirdPlatformReqDTO, HttpServletRequest request) {
        String platform = userLoginByThirdPlatformReqDTO.getPlatform();
        Integer appPlatform = userLoginByThirdPlatformReqDTO.getAppPlatform();
        String tempCode = userLoginByThirdPlatformReqDTO.getTempCode();
        String sign = userLoginByThirdPlatformReqDTO.getSign();
        QueryWrapper queryWrapper = new QueryWrapper();
        UpdateWrapper updateWrapper = new UpdateWrapper();
        String unionid = "";
        // 通过 tempCode 获取 unionId
        if ("1".equals(platform)) {
            // QQ  tempCode --> access_token
            unionid = OAuthUtil.getUnionid4QQ(tempCode);
        } else if ("2".equals(platform)) {
            // 微信 tempCode --> code
            JSONObject jsonObj = OAuthUtil.getUnionid4Wx(tempCode);
            unionid = jsonObj.getString("unionid");
        }
        // 如果获取unionId失败
        if (StringUtils.isBlank(unionid)) {
            return ResponseData.getFail("获取第三方授权信息失败!");
        }
        //进行业务逻辑的操作
        TUserinfo userInfo = userInfoMapper.getUserInfoByUnionId(unionid, Integer.parseInt(platform));
        RedisUtil.saveUnionid(platform, tempCode, unionid);
        //通过unionid查询是否绑定
        //已绑定,跳转至APP的首页
        if (userInfo != null && unionid != null) {
            //调用普通登录方法跳转至APP首页
            queryWrapper.eq("user_id", userInfo.getUserId());
            TUserinfo tUserinfo = tUserInfoMapper.selectOne(queryWrapper);
            UserLoginReqDTO userLoginReqDTO = new UserLoginReqDTO();
            userLoginReqDTO.setLoginId(tUserinfo.getPhone());
            userLoginReqDTO.setPassword(tUserinfo.getPassword());
            userLoginReqDTO.setAppPlatform(appPlatform);
            userLoginReqDTO.setIsApp(1);
            userLoginReqDTO.setLoginMode(1);
            userLoginReqDTO.setSkipPageApp("0");
            return this.userLogin(userLoginReqDTO, request);
        } else {
            //已注册未绑定,来源是登录后 个人中心-修改个人资料 跳转至已有界面未绑定页面(能登陆证明是老用户)
            if ("1".equals(sign)) {
                UserLoginRespDTO userLoginRespDTO = new UserLoginRespDTO();
                queryWrapper.eq("user_id", userInfo.getUserId());
                TUserinfo tUserinfo = tUserInfoMapper.selectOne(queryWrapper);
                userLoginRespDTO.setSkipPageApp("1");
                userLoginRespDTO.setPhone(tUserinfo.getPhone());
                userLoginRespDTO.setUnionid(unionid);
                return ResponseData.getSuccess(userLoginRespDTO);
            }
            //未注册未绑定,来源是未登录的学生端首页 跳转至第三方注册页面(因为未登录状态无法判断用户为新的还是老用户,同一跳到第三方注册页面)
            else {
                UserLoginRespDTO userLoginRespDTO = new UserLoginRespDTO();
                userLoginRespDTO.setSkipPageApp("2");
                userLoginRespDTO.setUnionid(unionid);
                return ResponseData.getSuccess(userLoginRespDTO);
            }
        }
    }

QQ授权,OAuthUtil.getUnionid4QQ()函数

 public static String getUnionid4QQ(String accessToken) {
        if (StringUtils.isBlank(accessToken)) {
            return null;
        }
        String requestUrl = "https://graph.qq.com/oauth2.0/me?";
        requestUrl += "unionid=1&access_token=" + accessToken;
        String resultStr = httpGet(requestUrl);
        if (StringUtils.isBlank(resultStr)) {
            return null;
        }
        // 返回格式为:callback(json数据);
        Pattern p = Pattern.compile("\\{.*?\\}");
        Matcher m = p.matcher(resultStr);
        if (!m.find()) {
            return null;
        }
        resultStr = m.group();
        JSONObject jsonObj = JSONObject.parseObject(resultStr);
        String unionid = jsonObj.getString("unionid");
        return unionid;
    }

微信授权,OAuthUtil.getUnionid4Wx()函数

    public static JSONObject getUnionid4Wx(String authorization_code) {
        if (StringUtils.isBlank(authorization_code)) {
            return null;
        }
        String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?";
        requestUrl += "appid=" + weixin_AppID + "&secret=" + weixin_AppSecret + "&code=" + authorization_code + "&grant_type=authorization_code";

        String resultStr = httpGet(requestUrl);
        JSONObject jsonObj = JSONObject.parseObject(resultStr);
        return jsonObj;
    }

参考文章:
https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/Development_Guide.html
https://cloud.tencent.com/developer/article/1677630
https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
https://blog.csdn.net/qq_32048567/article/details/82759347

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值