ByteDance MicroApp Login

2020-05-23  本文已影响0人  JunChow520

对比微信小程序登录流程

微信小程序登录流程

字节跳动小程序登录

登录流程

客户端

客户端使用tt.login()方法获取登录临时凭证code值,code值有效期3分钟。客户端获取code之后需通过调用服务端接口来向小程序后端发起登录凭证校验以获取用户信息。

tt.login({force:boolean, success:function, fail:function, complete:function});

接口参数

参数 类型 默认值 必填 描述
force boolean true N 是否强制调起登录框
success function - N 登录成功回调函数
fail function - N 登录失败回调函数
complete function - N 登录完成回调函数,不管成功或失败都会执行。

调起登录框

force:boolean = true

登录失败

fail:function(res){
  console.log("login fail", res.errMsg);
  tt.showToast({title:"登录失败", duration:2000});
}

fail登录失败回调函数,返回一个具有errMsg登录失败信息参数的对象。

success:function(res){
      const code = res.code;
      const anonymousCode = res.anonymousCode;
      const isLogin = res.isLogin;
}

登录成功

success登录成功回调函数携带一个object对象类型的参数返回,object对象包含属性分别是codeanonymousCodeisLoginerrMsg

例如:

{errMsg: "login:ok", anonymousCode: "7f50f5eda4923235", code: "231be4a26fec3d23", isLogin: true}
属性 类型 描述
errMsg string 错误信息
isLogin boolean 是否已登录
code string 登录临时凭证
anonymousCode string 匿名登录凭证

isLogin布尔值,用于判断在当前App中用户是否已经处于登录状态。

临时登录凭证

匿名登录凭证

临时登录凭证code和匿名登录凭证anonymousCode在向服务端请求时都只能使用1次

例如:客户端进入首页立即执行登录操作

$ vim pages/index/index.js
Page({
  onLoad: function () {
    const self = this;
    console.log('Welcome to Mini Code');
    tt.login({force:true, success:function(res){
      console.log("login success", res);
      const isLogin = res.isLogin;
      if(isLogin){
        const code = res.code;
        const anonymousCode = res.anonymousCode;

        let data = {code, anonymousCode};
        let url = "http://127.0.0.1:7001/api/bytedance/code2session";
        self.httpGet(url, data, function(res){
        }, function(res){
        });
      }
    },fail:function(res){
      const anonymousCode = res.anonymousCode;
      console.log("login fail", res.errMsg);
      tt.showToast({title:"登录失败", duration:2000});
    }});
  },
  httpGet:function(url, data, success, fail){
    const method = "GET";
    const dataType = "json";
    const header = {"content-type":"application/json"};
    const responseType = "text";
    tt.request({method, dataType, header, responseType, data,  url, success:function(res){
      console.log("request success", res);
      success(res);
    }, fail(res){
      console.log("request fail", res);
      fail(res);
    }});
  }
});

获取用户信息

//获取用户基本信息
tt.getUserInfo({
    fail(res){
      console.log("用户信息获取失败");
    },
    success(res){
      console.log(res);                              
    }
});

tt.getUserInfo获取已登录用户的基本信息或特殊信息,需用户授权后方可调用,依赖于登录接口,调用前确定已调用tt.login

tt.getUserInfo({success, fail, complete, withCredentials});
参数 类型 默认 必须 描述
success function - N 成功回调
fail function - N 失败回调
complete function - N 结束回调
withCredentials boolean false N 是否需返回敏感数据

成功返回

{
  errMsg: "getUserInfo:ok", 
  rawData: "{"nickName":"junchow","avatarUrl":"http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/3795/3033762272~120x256.image","gender":0,"city":"","province":"","country":"中国","language":""}",
  userInfo: {…}
}
属性 类型 说明
userInfo object 用户信息
rawData string 原始数据,userInfo的JSON字符串形式。

userInfo用户信息所包含的字段

{
  avatarUrl: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/3795/3033762272~120x256.image"
  city: ""
  country: "中国"
  gender: 0
  language: ""
  nickName: "junchow"
  province: ""
}
参数 类型 描述
avatarUrl string 用户头像
nickName string 用户昵称
gender number 用户性别 0未知 1男性 2女性
city string 用户城市
province string 用户省份
country string 用户国家
language string 用户语言

解码敏感数据

//获取用户基本信息
tt.getUserInfo({
    withCredentials:true,
    fail(res){
      console.log("用户信息获取失败");
    },
    success(res){
      console.log(res);                              
    }
});

若输入中传递了withCredentials:true参数则返回对象的参数会增加如下扩展属性

{
  errMsg: "getUserInfo:ok", 
  encryptedData: "ZM0mKGYyL+NdCTpl5OC6zzQuLMXjp1oQyHAcqEpAiXHc4SRs5g…7rtekDrIB5nWrHLYGnrSmBfDoK6epKglBGRd1uVHjZWW6+Zj8", 
  iv: "lS+u05jr8obZ5YOtuvet7A==", 
  signature: "d82e33764cefd6cc90b1f58c9ac180055f38e6df", 
  rawData: "{"nickName":"junchow","avatarUrl":"http://sf1-ttcd…y":"","province":"","country":"中国","language":""}", 
  userInfo: {nickName: "junchow", avatarUrl: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/3795/3033762272~120x256.image", gender: 0, city: "", province: "", …}
}
属性 类型 说明
signature string 签名,用于校验用户信息是否被篡改。
encryptedData string 加密数据,包括敏感信息在内的已加密用户数据。
iv string 加密算法参数

敏感数据可提供后端进行验证后保存到数据库

signature签名算法:校验数据合法性

const crypto = require("crypto");

const sha1 = val=>crypto.createHash("sha1").update(val).digest("hex");

const sigature = sha1(`${rawData}${session_key}`)

encryptedData敏感数据解析

const crypto = require("crypto");

const decipher = crypto.createDecipheriv(
  "aes-128-cbc",
  Buffer.from(sessionKey, "base64"),
  Buffer.from(iv, "base64")
);

let ret = decipher.update(encryptedData, "base64");
ret += decipher.final();

let data = JSON.parse(ret);

解密后的encryptdData可获得属性

属性 类型 描述
openId string 用户 openId
watermark object 敏感数据水印
avatarUrl string 用户头像
nickName string 用户昵称
gender number 用户性别 0未知 1男性 2女性
city string 用户城市
province string 用户省份
country string 用户国家
language string 用户语言

watermark敏感数据水印属性包括

属性 类型 描述
appid string 数据源小程序 id
timestamp number 时间戳,可以用于检查数据的时效性。

错误说明

{"error": "error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length"}

服务端

服务端登录接口为code2session,即客户端请求login接口获取到登录凭证codeanonmousCode后,
在服务端发送code2session请求以获取会话密钥session_keyopenid

会话密钥

接口地址

GET https://developer.toutiao.com/api/apps/jscode2session

接口参数

参数 描述
appid 小程序AppID,开发者后台获取。
secret 小程序AppSecret,开发者后台获取。
code 前端tt.login接口返回的临时登录凭证
anonymous_code 前端使用tt.login接口返回的匿名登录凭证

错误返回

data:{ 
  errcode: 40018, 
  errmsg: 'bad code', 
  error: 3, 
  message: 'bad code' 
},
字段 类型 描述
errcode number 错误编号
errmsg string 错误信息

错误编码

errcode errmsg
-1 系统错误
0 请求成功
40015 appid错误
40017 secret错误
40018 code错误
4019 anonmous_code错误
其它 参数为空

成功返回

data: {
  anonymous_openid: '',
  error: 0,
  openid: 'I25ZjrxP5R0xjrlj',
  session_key: 'WpUS27etxV7AQ9VBaToDbA=='
}
参数 描述
error 是否出错,0否1是。
openid 用户在当前小程序的ID,仅在请求时存在code参数时才会返回。
session_key 会话密钥,仅在请求时存在code参数时才返回。
anonmous_openid 匿名用户在当前小程序中的ID,尽在请求时存在anonymous_code时才返回。
上一篇下一篇

猜你喜欢

热点阅读