QQ登录实现

项目中接入QQ登录

接上篇介绍申请APPID和APPKEY的文章,本篇文章介绍如何将QQ登录接入自己的项目。(申请成功后,将你自己APPID和回调地址填上,点击QQ登录正常要能弹出登陆页面)
在这里插入图片描述

QQ登录的流程

  1. 点击qq登录,弹出登陆页面,授权登录。
  2. 页面会自动重定向到你填写的回调地址并拼接一个code参数。
  3. 通过使用code,向qq接口请求获取用户信息并返回前端。

分析

最开始我以为是在自己后端中实现回调地址接口,因为QQ是根据回调地址将code值传给我们,但想了一下,这样虽然没问题,后端能拿到code,并向qq发送请求获取用户信息,但获取到的用户信息好像返回不了给前端,因为这个回调请求不是前端发起的。后来看视频才知道,回调地址是前端的一个地址。前端页面通过获取地址栏的code后,再将code向发送给后端,后端拿到code获取到用户信息后就能返回给前端了。

综上,前端得有一个对应回调地址的页面,通过 location.search 获取到地址栏的code值,最后,在向后端接口发请求,将code值传递过去,后端接口进行相应的操作。这里的回调地址页面不需要任何内容,就是一个空页面。

不过有一点注意,回调地址由于是域名,但我们在本地测试,启动的项目访问地址都是localhost,所以可以在本地的hosts文件里面添加一个域名解析,将你的域名解析成127.0.0.1,并且启动前端的时候,将前端项目设置为80端口。

##本地host文件  C:\Windows\System32\drivers\etc 下的hosts文件
## 在文件最后加上  127.0.0.1   域名
## 改hosts文件直接先在其他位置创建一个hosts.txt 把hosts文件中的内容拷贝到hosts.txt文件中,并在最后添加域名解析,最后改为hosts,直接替换etc下的,直接修改hosts有权限问题 

在这里插入图片描述
在这里插入图片描述

前端可能重定向后出现 invalid host header 问题(没有就忽略),好像是前端禁止域名访问导致的,在前端配置文件vue.config.js的devServer中添加以下代码

    allowedHosts: [
      'xxxx.com', // 允许访问的域名地址,即花生壳内网穿透的地址
      '.xxxx.com'   // .是二级域名的通配符   
    ],

代码

前端对应的回调地址页面代码

<template>
    <div>
        登录中...
    </div>
</template>


<script>
import request from '../utils/request'
export default {
    name: "login",
    created() {
        let param=location.search    //param的值为  ?code=value
        let code=param.split("=")[1]  //code的值为  value 
        console.log(code)
        this.login(code)
    },
    methods: {
        login(code) {
            request.get("/qqlogin?code="+code).then(res => {     //这里的接口和你自己后端实现的一致
                console.log(res.data);   //这里就可以根据你自己的前端逻辑来操作数据或者跳转页面了
            })
        }
    }
};
</script>

前端路由中记得配上

// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import Home from '../components/Home'
import Login from '../components/Login'

//创建并暴露一个路由器
export default new VueRouter({
    mode: 'history',
	routes:[
		{
			path:'/home',
			component:Home
		},
		{
			path:'/login',
			component:Login
		}
	]
})

后端接口 /qqlogin 的代码

    @GetMapping("/qqlogin")
    public User callback(String code, HttpServletResponse response) throws IOException {
        String accessToken = QQLoginUtil.getAccessToken(code);
        String openId = QQLoginUtil.getOpenId(accessToken);
        return QQLoginUtil.getUserInfo(accessToken, openId);
    }

QQLoginUtil就是把那些调用qq接口的操作封装了一下,代码如下。代码中的接口和参数以及返回值都是官网有说明的,感兴趣的可以官网看看。

public class QQLoginUtil {

    private static String appid = "";   //你自己的

    private static String appkey = "";

    private static String redirect_url = "";


    private static RestTemplate restTemplate = new RestTemplate(); //可以用其他的http客户端工具

    /**
     * 根据code拿到access_token
     * @param code
     * @return
     */
    public static String getAccessToken(String code) {
        String access_token_url = "https://graph.qq.com/oauth2.0/token?fmt=json&" + "grant_type=authorization_code" + "&client_id=" + appid + "&client_secret=" + appkey + "&redirect_uri=" + redirect_url + "&code=" + code;
        String json = restTemplate.getForObject(access_token_url, String.class);
        JSONObject result = JSONUtil.parseObj(json);
        String access_token = (String) result.get("access_token");
        return access_token;
    }

    /**
     * 根据access_token拿到openid  这个openid其实就是用户唯一的身份,可以存数据库作为用户唯一标识
     * @param access_token
     * @return
     */
    public static String getOpenId(String access_token) {
        String openid_url = "https://graph.qq.com/oauth2.0/me?fmt=json&access_token=" + access_token;
        String json = restTemplate.getForObject(openid_url, String.class);
        JSONObject entries = JSONUtil.parseObj(json);
        String openid = (String) entries.get("openid");
        return openid;
    }


    /**
     * 根据openid 拿到用户的基本信息,包括头像,昵称等
     * @param access_token
     * @param openid
     * @return
     */
    public static User getUserInfo(String access_token, String openid) {
        String get_userinfo_url = "https://graph.qq.com/user/get_user_info?fmt=json&access_token=" + access_token + "&oauth_consumer_key=" + appid + "&openid=" + openid;
        String json = restTemplate.getForObject(get_userinfo_url, String.class);
        System.out.println(json);
        JSONObject result = JSONUtil.parseObj(json);
        User user = new User();
        user.setName((String) result.get("nickname")).setSex((String) result.get("gender")).setImage((String) result.get("figureurl_qq"));
        return user;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值