SpringBoot - OAuth2第三方登录之QQ登录

之前写过一篇OAuth2 - 第三方登录之新浪登录,也写过一篇OAuth2 - 第三方登录之微信登录,提到过QQ审核很复杂,我之前提交审核很多次,各种原因失败,这一次总算成功了,所以便来记录一下其中过程。

QQ登录需要做哪些准备?

1、服务器+备案过的域名。
2、一个能跑起来的服务,且登录页面正常,有QQ登录的跳转按钮。
可以通过ICP备案这个网站去查询你的备案信息。
在这里插入图片描述
红框标出来的,就是下面创建应用要使用的。

QQ互联 - 创建应用

进入到QQ互联官网,登录之后需要先进行一把开发者身份认证(需要手持身份证)。开发者身份审核通过之后,就可以去应用管理里创建一个网页应用。

1、基本资料填写

这里需要注意的就是备案域名对应的网站名,这个不能随便瞎填,必须和你备案域名的那个网站名字一致,我因为这里乱填审核失败过。
在这里插入图片描述

2、备案信息填写

网站地址:就是你准备在服务器上跑起来的那个应用的首页(我是直接搞了个登录页),或者说就是你备案的那个网站首页地址
回调地址:授权登录成功之后回调的地址,回调方法里你可以获取QQ信息和保存信息等。
提供方:理论上说,就是备案域名的主办方单位名称,也就是你的姓名。我填的阿里云(在阿里买的域名并备案),通过审核了。
网站地址备案号:就是网站备案/许可证号
网站图标:这个最好搞个正常一点的图标,我因为这个审核失败过。
在这里插入图片描述
创建应用,等待审核就好了,工作日一般半天就能有结果。

★注意★

提交审核前,你得保证你的服务已经在服务器上跑起来了,能通过你填的网站地址能够访问。我之前想快速通过审核,就弄了一个a标签写了个QQ登录,点击跳转QQ登录,然后审核失败了。
然后我就去网上随便找了一个登录的前端页面,然后通过Thymeleaf的方式放在我的SpringBoot项目里,将QQ相关的代码写好,然后打包在服务器上跑起来,这样才通过了审核。
在这里插入图片描述

SpringBoot整合QQ登录

QQ互联里并没有提供Java的SDK,也就是说你要自己写的话,比较麻烦。我在QQ开放Wiki里找到了JavaSdk,是民间大佬提供的(13年的时候)。

1、引入Sdk依赖

创建一个SpringBoot项目,并且引入Thymeleaf的依赖。(因为我觉得Thymeleaf很快能写出这个Demo,所以就用了)

<!-- QQ登录 - JavaSdk -->
<dependency>
    <groupId>net.gplatform</groupId>
    <artifactId>Sdk4J</artifactId>
    <version>2.0</version>
</dependency>

2、在resources创建一个qq的配置文件

创建qqconnectconfig.properties配置文件,按照下面的内容进行配置,主要修改appIdappKeyredirect_URI这三个即可。这配置文件名不能变,因为这是Sdk里用到的。如果你有兴趣,可以引入这个SDK之后看一下源码,自己重新搞个SDK也可以。我大概看了下源码,没什么难度,只是没时间重构一个SDK。

# appId
app_ID =
# appKey
app_KEY =
# 回调地址
redirect_URI =
# 更多接口:add_topic,add_one_blog,add_album,upload_pic,list_album,add_share,check_page_fans,add_t,add_pic_t,del_t,get_repost_list,get_info,get_other_info,get_fanslist,get_idollist,add_idol,del_ido,get_tenpay_addr
# 接口 - get_user_info(获取用户信息)
scope = get_user_info
baseURL = https://graph.qq.com/
getUserInfoURL = https://graph.qq.com/user/get_user_info
accessTokenURL = https://graph.qq.com/oauth2.0/token
authorizeURL = https://graph.qq.com/oauth2.0/authorize
addTopicURL = https://graph.qq.com/shuoshuo/add_topic
addShareURL = https://graph.qq.com/share/add_share
checkPageFansURL = https://graph.qq.com/user/check_page_fans
delTURL = https://graph.qq.com/t/del_t
getWeiboOtherUserInfoURL = https://graph.qq.com/user/get_other_info
getFansListURL = https://graph.qq.com/relation/get_fanslist
getIdolsListURL = https://graph.qq.com/relation/get_idollist
delIdolURL = https://graph.qq.com/relation/del_idol
getRepostListURL = https://graph.qq.com/t/get_repost_list
version = 2.0.0.0
getOpenIDURL = https://graph.qq.com/oauth2.0/me
addBlogURL = https://graph.qq.com/blog/add_one_blog
addAlbumURL = https://graph.qq.com/photo/add_album
uploadPicURL = https://graph.qq.com/photo/upload_pic
listAlbumURL = https://graph.qq.com/photo/list_album
addTURL = https://graph.qq.com/t/add_t
addPicTURL = https://graph.qq.com/t/add_pic_t
getWeiboUserInfoURL = https://graph.qq.com/user/get_info
addIdolURL = https://graph.qq.com/relation/add_idol
getTenpayAddrURL = https://graph.qq.com/cft_info/get_tenpay_addr

3、准备一个漂亮的前端登录页

在这里插入图片描述

4、书写一个Controller

这个Controller,就是实现QQ登录用到的一些方法。这一步完成,就基本完成了,剩下的就是打包,然后去服务器跑起来,然后去提交审核等待结果即可。

@Controller
public class LoginController {

    /**
     * 跳转至登录成功页
     */
    @RequestMapping("/index")
    public String admin(Model model){
        model.addAttribute("name", "柳成荫");
        model.addAttribute("headImgUrl", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202003%2F13%2F20200313175003_uwnff.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1642343525&t=149d9cba97279089bd7f0eceebc0d5cb");
        model.addAttribute("openId","123456");
        return "index";
    }

    /**
     * QQ登录请求
     */
    @RequestMapping("/loginByQQ")
    public void loginByQq(HttpServletRequest request, HttpServletResponse response) {
        // html类型,以网页形式打开
        response.setContentType("text/html;charset=utf-8");
        try {
            response.sendRedirect(new Oauth().getAuthorizeURL(request));
            System.out.println("In the QQ login...");
        } catch (QQConnectException | IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * QQ登录回调方法
     * @return
     */
    @RequestMapping("/login/qqLogin")
    public String connection(HttpServletRequest request, HttpServletResponse response, Model model) {
        try {
            // 获取AccessToken, getAccessTokenByRequest
            AccessToken accessTokenObj = (new Oauth()).getAccessTokenByRequest(request);
            String accessToken = null, openID = null;
            long tokenExpireIn = 0L;
            if (StringUtils.isEmpty(accessTokenObj.getAccessToken())) {
                System.out.println("Login Failed, accessToken is blank");
                // 未获取到accessToken,可以考虑:跳转回登录界面附带一个参数进行错误提示
                return "error";
            } else {
                accessToken = accessTokenObj.getAccessToken();
                // token过期时间 - 10分钟
                tokenExpireIn = accessTokenObj.getExpireIn();
                System.out.println("accessToken" + accessToken);
                request.getSession().setAttribute("demo_access_token", accessToken);
                request.getSession().setAttribute("demo_token_expirein", String.valueOf(tokenExpireIn));

                // 根据AccessToken获取OpenId
                OpenID openIDObj = new OpenID(accessToken);
                openID = openIDObj.getUserOpenID();
                // 获取用户信息,2021.12.27-2022.1.1全部返回2(默认值),2022年1月1日开始不再返回gender字段
                UserInfo userInfo = new UserInfo(accessToken, openID);
                UserInfoBean userInfoBean = userInfo.getUserInfo();
                // 返回码为0是正常返回,其他表示错误。
                if (userInfoBean.getRet() == 0) {
                    // 获取昵称,需要去除表情、特殊符号
                    String name = removeNonBmpUnicode(userInfoBean.getNickname());
                    // 头像Url
                    String imgUrl = userInfoBean.getAvatar().getAvatarURL100();
                    model.addAttribute("headImgUrl",imgUrl);
                    model.addAttribute("name",name);
                    model.addAttribute("openId",openID);
                } else {
                    System.out.println("QQ Login Failed, Reason is: " + userInfoBean.getMsg());
                    return "error";
                }
            }
        } catch (QQConnectException e) {
            e.printStackTrace();
            return "error";
        }
        return "index";
    }

    @GetMapping("/")
    public String goLogin(){
        return "login";
    }

    @GetMapping("/error")
    public String loginFailed(){
        return "error";
    }


    /**
     * 处理掉QQ网名中的特殊表情
     */
    public String removeNonBmpUnicode(String str) {
        if (str == null) {
            return "QQ登录用户";
        }
        str = str.replaceAll("[^\\u0000-\\uFFFF]", "");
        if ("".equals(str)) {
            str = "QQ登录用户";
        }
        return str;
    }
}

源码获取

Gitee:QQ登录Demo - Gitee地址
同时,也欢迎关注我的微信公众号:柳成荫同学

  • 1
    点赞
  • 3
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

九月清晨柳成荫

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值