# 账号

对接厂商的账号体系,支持接口如下:

名称 功能说明
qa.isAccountLogin 判断账户登录状态
qa.getAccountProvider 获取服务提供商
qa.getAccountProfile 获得用户基本信息
qa.accountAuthorize 进行 OAuth 授权
qa.getAccountPhoneNumber 获取当前手机登录的厂商账号的手机号码

目前支持的厂商明细如下:

厂商 支持 备注
vivo YES vivo帐号授权登录服务
OPPO YES OPPO开放平台
华为 YES 华为开发者联盟

# 接入指南

# 一、选择合适的授权模式

对于账号授权登录,我们提供授权码/标准模式、简化模式两种方案供开发者选择。

# 授权码模式/标准模式(authorization code)

是功能最完整、流程最严密的授权模式。其特点是通过开发者的后台服务器,与厂商的认证服务器进行交互。授权码模式下的登录流程与小程序登录大体一致。

# 简化模式(implicit grant type)

不通过第三方应用程序的服务器,跳过"授权码"步骤,直接在客户端向认证服务器申请令牌。所有步骤在客户端中完成,令牌对访问者是可见的,且客户端不需要认证。

这两类模式各有自己的应用场景,在选择上除非您的应用没有服务端,否则我们强烈建议你选择使用授权码模式授权。

相对于简化模式来说,虽然授权码模式多了一次请求,但是在授权码模式下可以基于 clientsecret 来验证 APP 的真实性。

同时授权码模式会下发刷新令牌,当访问令牌过期时可以通过刷新令牌在后台静默更新访问令牌,而无须再次让用户授权。

# 二、申请APPID和APPKEY

如果选择授权码模式,需要到上述各厂商平台上申请快应用的APPID和APPKEY

缩略语/术语 全称 说明
appId 应用ID 厂商对第三方快应用的唯一性标识,在接入前申请的appId做为clientId
appKey 第三方服务器密钥 第三方访问认证服务器的密钥,用于签名,不能在公网中传输,在接入前申请的appKey做为clientSecret / appSecret
accessToken 访问令牌 在用户授权许可下,认证服务器下发给客户端的授权凭证,可以用accessToken获取用户授权的信息(一般情况下是在第三方服务端发起请求,快应用也可通过qa.getAccountProfile接口在客户端获取用户信息)
refreshToken 刷新令牌 刷新令牌的作用在于更新访问令牌。访问令牌的有效期一般较短,当访问令牌失效时,可以利用刷新令牌去认证服务器换取新的访问令牌,是否需要该令牌是由第三方自行选择
redirectUri 重定向URI 授权模式下请求code时,用开发者平台上配置的回调地址请求厂商服务器进行校验,非必填

# 三、流程和示例代码

# 授权码模式

# 流程图

drawing

# 客户端

qa.accountAuthorize({
  type: 'code', // 授权码模式
  success: data => {
    // 把客户端获取到的授权码和厂商名称传到应用服务端
    qa.request({
      url: `https://mysite.com/authorize?code=${data.code}&provider=${qa.getAccountProvider()}`, //仅为示例,并非真实的接口地址
      success(res) {
        console.log(res.data)
      }
    })
  },
  fail: data => {
    console.log(`handling fail, code = ${data.errCode}`)
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 服务端

以nodeJs为例(其他服务端版本可到各厂商平台参考示例代码)

const express = require('express')
const request = require('request')
const md5 = require('md5');
const app = express()
const port = 3000

app.get('/authorize', (req, res, next) => {
  const code = req.query.code // 客户端获取的授权码
  const provider = req.query.provider // 可以根据厂商类型做不同处理

  // 此处以vivo账号接入为例,其他厂商可能略有差异
  if (provider === 'vivo') {
    const headers = { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' }
    const client_id = 'your_appid' // 第三方的唯一性标识,填入平台申请的appid
    const secret = 'your_appkey' // 用于签名的appsecret,填入平台申请的appkey
    const grant_type = 'authorization_code' // 授权类型,固定值: authorization_code
    const nonce = 'e1ed5c619a1d7eba2b7b109df873eae8' // 8位或32位随机字符串
    const timestamp = Date.now() // 当前时间戳
    let text = `client_id=${client_id}&code=${code}&grant_type=${grant_type}&nonce=${nonce}&timestamp=${timestamp}` // 由参数对组成的即将用于签名的字符串,按参数名字母升序排列
    let sign = md5(text + secret) // 签名
    let url = `https://passport.vivo.com.cn/oauth/2.0/access_token?${text}&sign=${sign}` // 请求token接口地址

    request.post(url, { headers }, (err, response, body) => {
      if (!err) {
        // 用返回的access_token通过接口获取用户信息
        text = `access_token=${JSON.parse(body).access_token}&client_id=${client_id}&nonce=${nonce}&timestamp=${timestamp}` // 由参数对组成的即将用于签名的字符串,按参数名字母升序排列
        sign = md5(text + secret) // 签名
        url = `https://passport.vivo.com.cn/oauth/2.0/resource?${text}&sign=${sign}` // 请求用户信息接口地址
        request.get(url, { headers }, (err, response, body) => {
          if (!err) {
            // 这里可以处理完自定义登录态后再返回
            res.json(JSON.parse(body));
          }
        })
        // 更多接口详情请到各厂商开发者平台上查看文档
      }
    })
  } else {
    next()
  }
})

app.listen(port, () => console.log(`Example app listening on port ${port}!`))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 简化模式

# 流程图

drawing

# 客户端

qa.accountAuthorize({
  type: 'token', // 简化模式
  success: data => {
    // 通过返回的accessToken获取用户信息
    qa.getAccountProfile({
      token: data.accessToken,
      success: res => {
        console.log(`handling success: ${res.nickname}`)
      },
      fail: res => {
        console.log(`handling fail, code = ${res.errCode} msg = ${res.errMsg}`)
      }
    })
  },
  fail: data => {
    console.log(`handling fail, code = ${data.errCode}`)
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

在线客服