💥【Chatterbox(话匣子)】如何在自己的网站中接入QQ登录?

830 阅读3分钟

背景

🎈Chatterbox(话匣子)实时聊天系统已经重构上线有两周了,有些小伙伴们觉得使用邮箱验证码登录太麻烦了,问我什么不用微信扫码登录。我想说的是我早就想这么做了,可是个体微信不让呀😡。

image.png

image.png

既然微信扫码走不通,那么咱们就退一步🤡。QQ理论上大家应该都有吧,那咱们就改成QQ登录吧😤!

QQ登录授权流程

用户点击QQ登录--->跳转QQ授权页--->点击授权--->携带授权凭证回跳目标页--->入参授权凭证请求后端完成注册/登录返回登录凭证--->跳转目标站点首页

image.png

准备工作

🐧QQ互联:connect.qq.com/

🗎参考文档:wiki.connect.qq.com/

  • 将站点完成备案
  • 网站上加上登录的相关逻辑(跳转QQ授权页,回跳页面),具体的业务可以先不用实现。
  • 在QQ互联上创建应用,需要域名,备案号,回调地址等信息。
  • 创建完成之后就可以拿到 APP ID、APP Key
  • 登录页实现授权逻辑(如果不实现的话会审核不通过)
  • 等待人工审核(我第一次申请大概5天左右有了反馈,后来发现QQ互联下面有个在线客服,可以在这里请他们帮忙加急审核😏)。

image.png

image.png

1719823133821.jpg

QQ授权

准备工作已经做完了,那就先来实现一下点击跳转QQ授权页。根据QQ互联文档所说,我们只需要跳转至https://graph.qq.com/oauth2.0/authorize页面并携带上主要参数即可。

image.png

授权跳转

const jumpToQQ = () => {
    const params = {
        which: 'Login',
        display: 'pc',
        client_id: 'QQ互联应用的APP ID',
        response_type: 'token',
        scope: 'all',
        redirect_uri: '授权完成之后跳转的页面'
    }
    const url = 'https://graph.qq.com/oauth2.0/show?' + parseJson2Param(params)
    window.open(url, '_self')
}

上面代码就是Chatterbox(话匣子)中实现的一部分代码。其中parseJson2Param函数就是参数转换成字符串,然后拼接到QQ互联授权地址后面。

授权回跳

const grantCallback = async () => {
  const path = route.fullPath.replace('#', '?')
  const accessToken = parseParam2Json(path).access_token
  if (accessToken) {
    const loading = ElLoading.service({
      text: 'QQ授权登录中...'
    })
    router.replace({ name: route.name })
    const r = await authStore.qqLogin({ accessToken })
    if (r) {
      loading.close()
      router.push({ name: 'conversation' })
    }
  }
}

授权完成之后,会跳转到设置的回调地址,然后我们就需要去获取地址中所携带的accessToken参数(文档中提到回跳之后地址后方会带上Authorization Code和原始的state值,然后通过 这个 Code 去获取 accessToken。但是我实际开发中发现回跳之后直接携带的是accessToken😖)。然后请求后端用accessToken去获取用户的openid和用户的信息,然后完成注册或者登陆(注册和登陆的逻辑就不一一列出来了)。

获取QQ用户OpenID,基本信息

🗎获取OpenId文档:wiki.connect.qq.com/%e8%8e%b7%e…

🗎获取用户信息文档:wiki.connect.qq.com/get_user_in…

private QqOpenIdDTO getQQUserOpenId(String accessToken) {
    String url = "https://graph.qq.com/oauth2.0/me";

    HashMap<String, Object> params = new HashMap<>(2);
    params.put("access_token", accessToken);
    params.put("fmt", "json");

    String result = HttpUtil.get(url, params);
    JSONObject jsonObject = JSONObject.parseObject(result);
    return jsonObject.toJavaObject(QqOpenIdDTO.class);
}
private QqUserDTO getQQUserInfo(String accessToken, String openId) {
    String url = "https://graph.qq.com/user/get_user_info";

    HashMap<String, Object> params = new HashMap<>(2);
    params.put("access_token", accessToken);
    params.put("openid", openId);
    params.put("oauth_consumer_key", qqConfig.getAppId());

    String result = HttpUtil.get(url, params);
    JSONObject jsonObject = JSONObject.parseObject(result);
    return jsonObject.toJavaObject(QqUserDTO.class);
}

上面为获取QQ授权用户信息的相关后端代码,开发到这里我发现没有使用到 App Key😂。

🦀🦀感谢看官看到这里,如果觉得文章不错的话,可以给小生的几个开源项目点个Star⭐!