前端第三方登录-QQ/微信登录

第三方登录前置条件

想要能通过第三方平台登录,先要经过第三方平台的同意,也就是在第三方平台进行对应的注册和认证。

针对QQ,我们需要QQ互联平台去注册和认证,注册和认证流程他们网站详细说明,在此不介绍。

页面交互上第三方登录流程

QQ登录为例

  1. 点击登录按钮,
  2. 弹出一个窗口,展示二维码
  3. 手机打开APP扫码,手机跳转到同意页面,点击同意;然后浏览器端的显示登录成功
  4. 手机显示登录成功后,会有两种情况
    1. 当前用户已经注册 => 直接登录
    2. 当前用户没有注册 => 执行注册流程,注册成功即可登录

前端代码上第三方登录做了哪些事情

QQ登录为例

  1. 点击第三方登录按钮,执行window.open方法,打开一个指定url窗口,该url指向第三方登录页面,里面会显示登录的二维码。
  2. 手机app扫码并且同意登录后,该第三方页面会跳转到登录成功页面,之所以知道登录成功,是因为该页面会一直轮询查询是否登录成功。
  3. 登录成功之后,该页面会进行跳转,跳转的url为我们预先指定的url,该页面能拿到第三方的用户信息,如昵称头像等,该信息为登录需要用到的信息。
  4. 到此,在第三方页面交互事情已经全部做完,剩余都是本平台内的事情。
    1. 判断该第三方用户是否在本平台已经注册(由后台判断),我们不能从第三方手中拿到用户关键信息(如手机号,密码等),只能拿到非关键信息如头像昵称,我们仅能通过拿到的第三方信息去判断有没有注册。
    2. 如果已经注册过,则直接登录
    3. 如果没有注册,执行注册功能(执行注册通常是让用户输入一个唯一标识如手机号,然后把这个唯一标识和第三方信息关联起来)

总结要做两件事

一:对接第三方平台获取第三方用户信息

二:利用该用户信息,完成注册

QQ登录对接流程(PC端)

总体流程分为以下几五步

  1. 展示 QQ 登录二维码
  2. 获取用户信息
  3. 完成跨页面数据传输
  4. 判断用户是否已注册
  5. 完成 QQ 对接

一:展示QQ二维码

首先我们需要在index.html中引入sdk,其中的appidredirecturi是我们在QQ平台注册和备案的时候生成的。

html 复制代码
<!-- QQ 登录 -->
<script type="text/javascript" charset="utf-8" src="https://connect.qq.com/qc_jssdk.js" data-appid="XXXX(你的 appid)" data-redirecturi="https://
xxxx(你配置的登录成功之后的回调)"></script>

在点击登录图标时候,通过window.open方法弹出第三方登录页面,这个登录页面的url是固定的,里面要传对应的clinet_id和回调url,这两个参数是在申请应用的时候配置生成的。

同时调用QQ登录挂起方法(该方法轮询查询登录成功没有)

js 复制代码
/**
 * 登录按钮事件
 */
const onQQLogin = () => {
  openQQWindow()
}

/**
 * 处理 QQ 登录视窗
 */

const openQQWindow = async () => {
  window.open(
    QQ_LOGIN_URL,
    'oauth2Login_10609',
    'height=525,width=585, toolbar=no, menubar=no, scrollbars=no, status=no, location=yes, resizable=yes'
  )
}

// QQ 登录挂起
onMounted(() => {
  QC.Login(
    {
      btnId: 'qqLoginBtn' //插入按钮的节点id
    },
    // 登录成功之后的回调,但是需要注意,这个回调只会在《登录回调页面中被执行》
    // 登录存在缓存,登录成功一次之后,下次进入会自动重新登录(即:触发该方法,所以我们应该在离开登录页面时,注销登录)
    (data, opts) => {
      console.log('QQ登录成功')
      console.log(data)
      // 注销登录,否则在后续登录中会直接触发该回调
      QC.Login.signOut()
    }
  )
})

二:获取用户信息

登录成功后,页面会跳转到我们提前配置好的登录页,QQ会返回给我们用户信息,后面步骤我们会通过返回的token判断该用户是否已经在本平台注册

js 复制代码
// 2. 获取当前用户唯一标识,作为判断用户是否已注册的依据
const accessToken = /access_token=((.*))&expires_in/.exec(
  window.location.hash
 
 // 3. 拼接请求对象
const oauthObj = {
  nickname: data.nickname,
  figureurl_qq_2: data.figureurl_qq_2,
  accessToken
}
console.log(oauthObj)

三:完成跨页面数据传输

上一步我们拿到的用户信息是在window.open打开的窗口拿到的,现在我们要把这些信息传递给父页面,这里要用到同源下 的跨页面传输技术,通常可以用BroadcastChannel对象或者是利用localStorage的onStorage事件存储实现,这里我们不做过多介绍。

四:判断用户是否已注册

父页面拿到用户信息后,立刻触发登录操作,发送登录接口,如果后台返回没有注册过,则跳转到注册页面,如果已经注册过,则登录成功。

js 复制代码
import store from '@/store'
import router from '@/router'
import { message } from '@/libs'

/**
 * 第三方登录统一处理方法
 * @param {*} oauthType 登录方式
 * @param {*} oauthData 第三方数据
 */
export const oauthLogin = async (oauthType, oauthData) => {
  const code = await store.dispatch('user/login', {
    loginType: oauthType,
    ...oauthData
  })
  // 返回  204 表示当前用户未注册,此时给用户一个提示,走注册页面
  if (code === LOGIN_TYPE_OAUTH_NO_REGISTER_CODE) {
    message('success', `欢迎您 ${oauthData.nickname},请创建您的账号`, 6000)
    // 进入注册页面,同时携带当前的第三方数据和注册标记
    router.push({
      path: '/register',
      query: {
        reqType: oauthType,
        ...oauthData
      }
    })
    return
  }

  // 否则表示用户已注册,直接进入首页
  router.push('/')
}

到此,已完成第三方登录流程

QQ登录对接流程(移动端)

移动端的登录流程和PC端基本一致,最大的不同就是,移动端没有新窗口的概念,移动端一共只有一个窗口。

所以在移动端中,我们需要在当前页面中,继续进行后续操作。不需要跨页面传输

js 复制代码
QC.Login(
    ...
    (data, opts) => {
      ...

      // 针对于 移动端而言:通过移动端触发 QQ 登录会展示三个页面,原页面、QQ 吊起页面、回调页面。并且移动端一个页面展示整屏内容,且无法直接通过 window.close() 关闭,所以在移动端中,我们需要在当前页面继续进行后续操作。
      oauthLogin(LOGIN_TYPE_QQ, oauthObj)
      // 5. 在 PC 端下,关闭第三方窗口
      window.close()
    }

微信对接登录

微信登录和QQ登录整体流程是相似的,但在具体代码实现上会有差别。

首先我们仍然要先去微信平台做注册,微信一共分为微信公众平台和微信开放平台。

微信公众平台

地址:mp.weixin.qq.com/

作用:用于管理、开放微信公众号(包括订阅号、服务号、企业号),相当于微信公众号的后台运营、管理系统。

微信开放平台

地址:open.weixin.qq.com/

作用:主要面对移动应用、网站应用开发者,为其提供微信登录、分享、支付等相关权限和服务.

注册过程不在此介绍。

微信登录总体实现步骤

  1. 通过 微信登录前置数据获取 接口,获取登录数据(比如 APP ID
  2. 根据获取到的数据,拼接得到 open url 地址
  3. 打开该地址,展示微信登录二维码
  4. 移动端微信扫码确定登录
  5. 从当前窗口中解析 window.location.search 得到用户的 code 数据
  6. 根据 appId、appSecret、code 通过接口获取用户的 access_token
  7. 根据 access_token 获取用户信息
  8. 通过用户信息触发 oauthLogin 方法

核心代码实现

触发微信登录,先从后台获取登录前置数据,然后通过window.open打开二维码页面地址,这个页面是的url同样是定死的,传参是从前置数据接口拿到的。

js 复制代码
/**
 * 触发微信登录
 */
const onWeiXinLogin = async () => {
  // 1. 通过微信登录前置数据获取接口,获取登录数据
  const { appId, appSecret, redirectUri, scope, state } = await getWXLoginData()
  // 2. 根据获取到的数据,拼接得到 `open url` 地址
  window.open(
    `https://open.weixin.qq.com/connect/qrconnect?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`,
    '',
    'height=525,width=585, toolbar=no, menubar=no, scrollbars=no, status=no, location=yes, resizable=yes'
  )
  // 等待扫码登录成功通知
  brodacast.wait().then(async ({ code }) => {
    console.log('微信扫码登录成功')
    console.log(code)
  })
}

微信登录成功之后,会 跳转到指定的 redirectUri 地址,并且把 code 放入到 location.search 中,所以我们可以在这里解析 search:

js 复制代码
/**
 * 微信登录成功之后的窗口数据解析
 */
if (window.location.search) {
  const code = /code=((.*))&state/.exec(window.location.search)[1]
  if (code) {
    brodacast.send({
      code
    })
    // 关闭回调网页
    window.close()
  }
}

到此,和微信的交互已经做完,剩下的都是自己网站内的交互。

根据微信返回的信息,获取access_token,然后根据access_token,获取用户信息

js 复制代码
// 等待扫码登录成功通知
brodacast.wait().then(async ({ code }) => {
  ...
  // 微信登录成功,关闭通知
  brodacast.clear()
  // 获取 AccessToken 和 openid
  const { access_token, openid } = await getWXLoginToken(
    appId,
    appSecret,
    code
  )
  console.log('access_token, openid')
  console.log(access_token, openid)
})


// 等待扫码登录成功通知
brodacast.wait().then(async ({ code }) => {
  ...
  // 获取登录用户信息
  const { nickname, headimgurl } = await getWXLoginUserInfo(access_token, openid)
  console.log(nickname, headimgurl)
})

拿到用户信息以后,发送登录接口

js 复制代码
// 等待扫码登录成功通知
brodacast.wait().then(async ({ code }) => {
  ...
  // 执行登录操作
  oauthLogin(LOGIN_TYPE_WX, {
    openid,
    nickname,
    headimgurl
  })
})

面试问第三方QQ/微信登录怎么做的,回答

待完成...

草稿

  1. 先注册...讲解..
  2. 交互讲解描述...
  3. 根据交互,讲核心代码的实现,点出关键步骤,不讲没用的细节。
  4. 总结微信和qq的异同,同样指点出关键步骤。
相关推荐
酷酷的阿云9 分钟前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
微信:1379712058711 分钟前
web端手机录音
前端
齐 飞17 分钟前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
神仙别闹34 分钟前
基于tensorflow和flask的本地图片库web图片搜索引擎
前端·flask·tensorflow
GIS程序媛—椰子1 小时前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_0012 小时前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端2 小时前
Content Security Policy (CSP)
前端·javascript·面试
木舟10092 小时前
ffmpeg重复回听音频流,时长叠加问题
前端
王大锤43912 小时前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
我血条子呢2 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js