记录开发内容demo-java第三方QQ登录


前言

第三方登录之PCQQ生成二维码 成功并回调


一、所需参数

    @Resource
    private RedisCache redisCache;

    @Resource
    private UserAccountService userAccountService;

    //应用AppID
    private String qqAppId="";

    //应用AppSecret
    private String qqAppSecre="";

    //回调方法路径
    yml配置
    project:
  	  servlet: xxx
    @Value("${project.servlet}")
    private String wxCallback;
	//模版
    private RestTemplate restTemplate = new RestTemplate();

二、前端调用接口

1.生成二维码

代码如下(示例):

    /**
     * 生成登录二维码
     * return: 前端展示二维码路径,可以直接用a标签包裹
     **/
    @GetMapping("/getCode")
    public R getCode(String type) throws UnsupportedEncodingException {
        String qqOauthUrl = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=APPID&redirect_uri=REDIRECT_URI&state=STATE";
        String qq_redirect_uri = URLEncoder.encode(qqCallback+"/qqLogin/qqCallback", "utf-8");
        qqOauthUrl =  qqOauthUrl.replace("APPID",qqAppId).replace("REDIRECT_URI",qq_redirect_uri);
        if ("1".equals(type))
            redisCache.setCacheObject("user",SecurityUtil.getCurrentUserId());
        return data(qqOauthUrl) ;
    }

2.成功回调

代码如下(示例):


   //回调方法(用户扫描二维码授权后调用)
    @GetMapping("/qqCallback")
    public void qqCallback(@RequestParam(name = "code", required = false) String code, HttpServletResponse response) throws IOException {
        if (code == null || "".equals(code)) {
//            return  R.error("用户禁止授权");
            return;
        }


        //1.通过code获取access_token
        String url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=APPID&client_secret=APPSECRET&code=CODE&redirect_uri=REDIRECT_URI";

        url = url.replace("APPID", qqAppId).replace("APPSECRET", qqAppSecre).replace("CODE", code).replace("REDIRECT_URI", qqCallback);
        //String tokenInfoStr = HttpRequestUtils.httpGet(url, null, null);
        ResponseEntity<String> tokenData = restTemplate.getForEntity(url, String.class);
        Map<String, String> tokenMap = new HashMap<>();
        if (tokenData.getStatusCodeValue() == 200) {
            String tokenStr = tokenData.getBody();
            String[] strs = tokenStr.split("&");
            for (String string : strs) {
                String key = string.split("=")[0];
                String value = string.split("=")[1];
                tokenMap.put(key, value);
            }
        } else {
//            return  R.error("用code获取access_token失败");
            return;
        }

        //2.通过access_token和openid获取用户信息
        String userInfoUrl = "https://graph.qq.com/oauth2.0/me?access_token=ACCESS_TOKEN";
        userInfoUrl = userInfoUrl.replace("ACCESS_TOKEN", tokenMap.get("access_token"));
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(userInfoUrl, String.class);
        if (responseEntity.getStatusCodeValue() == 200) {
            JSONObject userInfoObject = ConvertToJson(responseEntity.getBody());
            if (userInfoObject.getString("openid") == null || "".equals(userInfoObject.getString("openid"))) {
//                return  R.error("获取用户信息失败");
                return;
            }
            //登录后唯一id
            String openid = userInfoObject.getString("openid");
            //------------业务处理
            LambdaQueryWrapper<UserAccount> wrapper = Wrappers.lambdaQuery(new UserAccount()).eq(UserAccount::getQqOpenid, openid).ne(UserAccount::getIsDelete, 1);
            UserAccount userAccount = userAccountService.getOne(wrapper);
            //判断是否是绑定第三方
            if (redisCache.getCacheObject("user") !=null ){
                LambdaQueryWrapper<UserAccount> wrapper1 = Wrappers.lambdaQuery(new UserAccount()).eq(UserAccount::getId, redisCache.getCacheObject("user")).ne(UserAccount::getIsDelete, 1);
                UserAccount userAccount1 = userAccountService.getOne(wrapper1);
                userAccount1.setWxOpenid(openid);
                //判断是否已被绑定
                if (userAccount !=null){
                    userAccount.setWxOpenid(null);
                    userAccountService.updateByPrimaryKey(userAccount);
                }
                userAccountService.updateByPrimaryKey(userAccount1);
                StpUtil.login(userAccount1.getId(), "pc");
                redisCache.deleteObject("user");
                response.sendRedirect("http://xxx/#/?token1=" + StpUtil.getTokenValue());
                //判断用户是否存在直接登录
            } else if (userAccount != null) {
                StpUtil.login(userAccount.getId(), "pc");
                response.sendRedirect("http://xxx/#/?token1=" + StpUtil.getTokenValue());
                //用户不存在注册登录
            }else{
                UserAccount userAccount1 = new UserAccount();
                String salt = "qazwsx";
                userAccount1.setSalt(salt);//加密方式、、、、、、
                String randomStr = String.valueOf((long) ((Math.random() * 9.0 + 1) * (Math.pow(10, 10 - 1))));
                userAccount1.setNickName(randomStr);
                userAccount1.setRegistrationTime(new Date());
                userAccount1.setType(0);
                userAccount1.setPicture("xxx");
                userAccount1.setWxOpenid(openid);
                userAccountService.save(userAccount1);
                StpUtil.login(userAccount1.getId(), "pc");
                response.sendRedirect("http://xxx/#/?token1=" + StpUtil.getTokenValue());
            }
            /**
             * 根据openid查询平台用户:
             *  1. 如果没有查询到用户,则将openid与平台用户绑定,或者注册新账户
             *  2. 如果查询到用户,则调用本地登录方法
             */
        } else {
//            return R.error("获取用户信息失败");
            return;
        }
        return;
    }

    private JSONObject ConvertToJson(String string) {
        string = string.substring(string.indexOf("(") + 1, string.length());
        string = string.substring(0, string.indexOf(")"));
        JSONObject jsonObject = JSONObject.parseObject(string);
        return jsonObject;
    }


总结

第三方QQ登录 首先调用生成二维码 扫码登陆成功后回调

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现第三方qq登录,可以使用QQ互联提供的开放平台接口。具体的步骤如下: 1. 注册成为QQ互联开发者,并创建应用。在创建应用时,需要填写应用的基本信息,并获得AppID和AppKey。 2. 在Spring Boot后端项目中,使用Spring Security实现OAuth2认证。在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-client</artifactId> <version>5.3.4.RELEASE</version> </dependency> ``` 3. 在前端Vue项目中,使用Vue CLI创建项目,并安装vue-cli-plugin-qrcode实现生成二维码。在Terminal中运行以下命令: ``` vue create qq-login-demo cd qq-login-demo vue add qrcode ``` 4. 在Spring Boot后端项目中,实现OAuth2的配置。在application.yml文件中添加以下配置: ```yaml spring: security: oauth2: client: registration: qq: clientId: <your app id> clientSecret: <your app key> redirectUriTemplate: "{baseUrl}/login/oauth2/code/{registrationId}" authorizationUri: https://graph.qq.com/oauth2.0/authorize tokenUri: https://graph.qq.com/oauth2.0/token userInfoUri: https://graph.qq.com/user/get_user_info scope: - get_user_info provider: qq: authorizationUri: https://graph.qq.com/oauth2.0/authorize tokenUri: https://graph.qq.com/oauth2.0/token userInfoUri: https://graph.qq.com/user/get_user_info?oauth_consumer_key={clientId}&openid={oauthId} userNameAttribute: nickname ``` 5. 在前端Vue项目中,实现二维码生成。在App.vue文件中添加以下代码: ```vue <template> <div id="app"> <div v-if="!isLogin"> <qrcode :value="qrCodeUrl"></qrcode> </div> <div v-else> <p>{{ userInfo.nickname }}</p> <img :src="userInfo.figureurl_qq_1" alt="头像"> </div> </div> </template> <script> import QRCode from 'qrcode' export default { name: 'App', data() { return { isLogin: false, qrCodeUrl: '' } }, mounted() { this.generateQRCode() }, methods: { async generateQRCode() { const response = await this.$http.get('/qq-login/qr-code') if (response.status === 200) { this.qrCodeUrl = response.data this.isLogin = false } }, async checkLoginStatus() { const response = await this.$http.get('/qq-login/check-login-status') if (response.status === 200) { this.userInfo = response.data this.isLogin = true } } } } </script> ``` 6. 在Spring Boot后端项目中,实现二维码生成和登录状态检查。在QqLoginController.java文件中添加以下代码: ```java @RestController @RequestMapping("/qq-login") public class QqLoginController { private final OAuth2AuthorizedClientService authorizedClientService; private final RestTemplate restTemplate; @Autowired public QqLoginController(OAuth2AuthorizedClientService authorizedClientService, RestTemplate restTemplate) { this.authorizedClientService = authorizedClientService; this.restTemplate = restTemplate; } @GetMapping("/qr-code") public String generateQRCode() { String qrCodeUrl = "https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=<your app id>&redirect_uri=http://localhost:8080/login&state=<random state>"; try { qrCodeUrl = QRCode.from(qrCodeUrl).to(ImageType.PNG).withSize(250, 250).stream().collect(Collectors.toBase64String); } catch (WriterException | IOException e) { e.printStackTrace(); } return "data:image/png;base64," + qrCodeUrl; } @GetMapping("/check-login-status") public Map<String, Object> checkLoginStatus() { OAuth2AuthenticationToken authenticationToken = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); OAuth2AuthorizedClient authorizedClient = authorizedClientService.loadAuthorizedClient(authenticationToken.getAuthorizedClientRegistrationId(), authenticationToken.getName()); String accessToken = authorizedClient.getAccessToken().getTokenValue(); String openId = restTemplate.getForObject("https://graph.qq.com/oauth2.0/me?access_token=" + accessToken, String.class); openId = StringUtils.substringBetween(openId, "\"openid\":\"", "\"}"); Map<String, Object> userInfo = restTemplate.getForObject("https://graph.qq.com/user/get_user_info?access_token=" + accessToken + "&oauth_consumer_key=<your app id>&openid=" + openId, Map.class); return userInfo; } } ``` 7. 在前端Vue项目中,实现登录状态检查。在App.vue文件中添加以下代码: ```vue <script> export default { name: 'App', data() { return { isLogin: false, qrCodeUrl: '' } }, mounted() { this.generateQRCode() this.checkLoginStatus() setInterval(() => { this.checkLoginStatus() }, 3000) }, methods: { async checkLoginStatus() { const response = await this.$http.get('/qq-login/check-login-status') if (response.status === 200) { this.userInfo = response.data this.isLogin = true } } } } </script> ``` 至此,我们就成功地实现了Spring Boot+Vue代码实现第三方QQ登录的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值