您的位置 首页 > 数码极客

【qq授权管理中心】QQ授权登录前后端实现(Vue+Spring Boot)

上一句话说明了微信批准登录的实现。本文主要介绍QQ授权登录的实现。

其登录过程与微信授权登录大体类似,不过不需要考虑普通H5和公众号两种情况,因此相对来说逻辑处理上要简单些。

1. 登录QQ开放平台申请网页应用

待应用审核通过后进入应用修改“平台信息”:

主要是网站回调域的配置,即QQ授权登录成功后返回的页面地址,可以配置多个,通过分号间隔。像上面我针对电脑端和H5页面分别配置了两个地址。


2. 处理流程

本人项目的主要流程如下(具体流程上可能会有不同,根据实际业务场景定):

  • 前端嵌入授权登录按钮,点击后跳转到后端组装授权请求地址及参数;
  • 前端跳转到后端返回的地址,此时如果是移动端会调起QQ应用进行授权登录,电脑端将会打开二维码;
  • 用户授权,成功后QQ将本次授权的Token返回到我们指定的页面中;
  • 在指定页面中解析Token,然后在后台通过Token调用QQ接口获取用户OpenId;
  • 在应用用户表中根据OpenId查找用户信息,如果已经存在,则直接调起本地登录然后将token返回前端,处理结束;
  • 如果未找到用户信息,那么需要调用QQ接口获取用户信息(如昵称等),然后返回前端进行用户账号绑定,绑定完后进行登录生成应用Token返回前端。


3. 实现细节

注意后端使用Vue实现,后端使用Spring Boot。

3.1 前端嵌入登录按钮

<div>    <img         src="~@/asse;         @click="$goPath('/user/login/qq-login')"         /> </div>

点击后跳转到qq-login页面,然后在qq-login页面中直接调用后端接口获取授权参数,获取成功后即跳转页面:

this.$get("/base/login/qq-login-page", { isMobile: true }).then(   (resp) => {        window.open(resp, "_self");   } );


3.2 后端授权参数组装接口

先要增加QQ操作的一个公共包,Maven配置:

<dependency>    <groupId>net.gplatform</groupId>    <artifactId>Sdk4J</artifactId>    <version>2.0</version> </dependency>

然后在项目资源文件目录下增加qqconnec文件,配置信息如下:

app_ID = 10***173 app_KEY = 6bb588****efc4da redirect_URI = mobile_redirect_URI = scope = get_user_info baseURL = getUserInfoURL = user/get_user_info accessTokenURL = oauth2.0/token authorizeURL = oauth2.0/authorize getOpenIDURL = oauth2.0/me addTopicURL = shuoshuo/add_topic addBlogURL = blog/add_one_blog addAlbumURL = photo/add_album uploadPicURL = photo/upload_pic listAlbumURL = photo/list_album addShareURL = share/add_share checkPageFansURL = user/check_page_fans addTURL = t/add_t addPicTURL = t/add_pic_t delTURL = t/del_t getWeiboUserInfoURL = user/get_info getWeiboOtherUserInfoURL = user/get_other_info getFansListURL = relation/get_fanslist getIdolsListURL = relation/get_idollist addIdolURL = relation/add_idol delIdolURL = relation/del_idol getTenpayAddrURL = cft_info/get_tenpay_addr getRepostListURL = t/get_repost_list version = 2.0.0.0

注意配置appId及appKey、redirect_uri,移动端还要配置mobile_redirect_uri。

注意配置的两个redirect_uri必须在QQ开放平台后台配置,也就是本文最开头所述,否则授权登录时将会报异常。

组装授权参数方法实现如下:

/**     * 获取登录地址     *     * @param mobile 是否移动端登录,移动端返回地址与WEB不一样     * @return 登录地址     */ public String getLoginPageUrl(boolean mobile) {    return QQConnec("authorizeURL").trim()        + "?client_id=" + QQConnec("app_ID")        + "&redirect_uri=" + (mobile ? QQConnec("mobile_redirect_URI") : QQConnec("redirect_URI"))        + "&response_type=token"; }


3.3 前端接收授权成功token

经过以上两步,前端页面将会调起QQ登录;用户同意后QQ将跳转到我们指定的redirect_uri上,并附带token参数;该页面实现如下:

<template>    <div class="qq-login">        <template v-if="u;>            <!-- 绑定用户 -->            <user-bind :initUserInfo="userInfo"></user-bind>        </template>    </div> </template> <script> import userBind from "@/components/UserBind"; export default {    components: { userBind },    props: {},    data() {        return {            token: "",            userInfo: {},       };   },    mounted() {         = (this.$rou); ();     },    methods: {        doLogin() {            this.$get("/base/login/qq", { token: })               .then((resp) => {                    if ) {                        // 用户已经绑定,登录成功,跳转首页                        this.$setCookie("accessToken", re);                        this.$cache(                            "userInfo",                            JSON.stringify)                       );                        this.$("login", true);                        this.$goAfterLogin();                   } else {                        // 进行用户绑定                         = {                            qqOpenId: re,                            nickname: re,                            image: re,                            sex: re,                       };                   }               })               .catch(() => {                this.$me("授权登录失败");           });       },                  parseToken(fullPath) {            // QQ返回的access_token是在#后的,需要进行特殊解析            if (fullPath) {                // 取最后一个位置的#                let idx = ("#");                if (idx === -1) {                    return null;               }                var restStr = (idx + 1);                if (!restStr) {                    return null;               }                restStr = restStr                   .split("&")                   .find((str) => ("access_token="));                if (!restStr) {                    return null;               }                return re(13);           }       },        loginSucceeded() {            this.$goAfterLogin();       },   }, }; </script><style lang="scss"> .qq-login {    .bind-form {        width: 400px;        margin: 0 auto;        padding: 30px 40px 10px 10px;        .title {            line-height: 50px;            font-size: 14px;       }   } } </style>

获取到token后会调用后端接口获取openId及用户信息


3.4 后端通过token获取用户信息

前端获取token后传给后台,由后台进行下一步处理,具体处理过程如下:

@GetMapping("/qq") public ThirdLoginResultDTO qqLogin(@RequestParam("token") String token) {    // 先获取openId    String openId = qqService.getOpenId(token);    ThirdLoginResultDTO result = new ThirdLoginResultDTO();    // 根据openId查询用户是否存在,存在则直接登录    Optional<UserDTO> userOptional = u(openId);    if ()) {        // 如果已经存在,直接登录后返回        UserDTO user = u();        BiValue<String, UserDTO> biValue = loginService.localLogin(user);        re(biValue);        re(true);        return result;   }    // 不存在,返回给前端相关信息并进行绑定    // 如果openId不存在,则需要将昵称等返回前端,在前端关联手机号进行绑定    ThirdUserInfo qqUserInfo = qqService.getUserInfo(token, openId);    re(false);    re(qqUserInfo);    return result; }

其中QQService 实现如下:

package com.; import com.liuqi.common.web.common.error.BusinessException; import com.qq.connect.QQConnectException; import com.qq.connect.a; import com.qq.connect.a; import com.qq.connect.javabeans.qzone.UserInfoBean; import com.qq.connect.u; import com.; import org.; import org.Factory; import org.; import javax.anno; import javax.; /** * QQ登录相关操作服务 * * @author LiuQi 2020/8/29-15:07 * @version V1.0 **/ @Service public class QQService {    private static final Logger logger = LoggerFac);    @Resource    private HttpServletRequest request;    /**     * 获取登录地址     *     * @param mobile 是否移动端登录,移动端返回地址与WEB不一样     * @return 登录地址     */    public String getLoginPageUrl(boolean mobile) {        return QQConnec("authorizeURL").trim()                + "?client_id=" + QQConnec("app_ID")                + "&redirect_uri=" + (mobile ? QQConnec("mobile_redirect_URI") : QQConnec("redirect_URI"))                + "&response_type=token";   }    /**     * 根据Token获取OpenId     *     * @param token 登录Token     * @return OpenId     */    public String getOpenId(String token) {        try {            return new OpenID(token).getUserOpenID();       } catch (QQConnectException e) {            logger.error("QQ服务调用失败", e);            throw Bu("QQ服务调用失败");       }   }    /**     * 获取QQ用户信息     *     * @param token token     * @return QQ用户信息     */    public ThirdUserInfo getUserInfo(String token, String openId) {        UserInfo userInfo = new UserInfo(token, openId);        UserInfoBean userInfoBean = null;        try {            userInfoBean = u();       } catch (QQConnectException e) {            logger.error("QQ服务调用失败", e);            throw Bu("QQ服务调用失败");       }        ThirdUserInfo qqUserInfo = new ThirdUserInfo();        qqU().getAvatarURL100());        qqU());        qqU().equals("男") ? 1 : 2);        qqU(openId);        return qqUserInfo;   }    /**     * 获取QQ用户信息     *     * @param token token     * @return QQ用户信息     */    public ThirdUserInfo getUserInfo(String token) {        String openId = (token);        return (token, openId);   } }


这样整个QQ授权登录过程就处理完了。相对来说比微信授权登录的要简单很多。)

关于作者: admin

无忧经验小编鲁达,内容侵删请Email至wohenlihai#qq.com(#改为@)

热门推荐