zoukankan      html  css  js  c++  java
  • 小程序之登录

    一、登录流程

    • 小程序内通过wx.login接口获得code
    • code传入后台,后台对微信服务器发起一个https请求换取openidsession_key(解密encryptedDataiv得到的)
    • 后台生成一个自身的3rd_session(以此为key值保持openidsession_key),返回给前端。PS:微信方的openidsession_key并没有发回给前端小程序
    • 小程序拿到3rd_session之后保持在本地
    • 小程序请求登录区内接口,通过wx.checkSession检查登录态,如果失效重新走上述登录流程,否则待上3rd_session到后台进行登录验证

    通过上面wx.loginwx.getUserInfo两个api拿到相应的信息,并通过上方接口传给自己的服务器.

    登录获取用户信息

    1
    2
    3
    4
    5
    6
    7
    wx.login({
    success(res){
    console.log(res)

    //errMsg:"login:ok"
    }
    })
    1
    2
    3
    4
    5
    wx.getUserInfo({
    success(res){
    console.log(res)
    }
    })

    返回的信息

    userInfo

    需要传输的信息有7个参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    appid  小程序唯一标识
    secret 小程序的 app secret
    js_code //wx.login登录时获取的 code,用于后续获取session_key

    //下面两个参数用户服务器端签名校验用户信息的
    signature 使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息。
    rawData 不包括敏感信息的原始数据字符串,用于计算签名。

    //下面两个参数是用于解密获取openId和UnionId的
    encryptedData 包括敏感数据在内的完整用户信息的加密数据
    iv 加密算法的初始向量
    • 可精简为以下三个参数.
    • 其余的签名校验的参数可省略,而appidsecret可以直接写在服务器.
    1
    2
    3
    js_code //  wx.login登录时获取的 code,用于后续获取session_key
    encryptedData 包括敏感数据在内的完整用户信息的加密数据
    iv 加密算法的初始向量

    服务端处理返回token、sessionId过程省略…

    二、登录态校验

    主要用到checkSession

    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
    wx.checkSession({
    success: (res) => {
    console.log('warning wx.checkSession OK, but no viewerId', res);
    },
    fail: (res) => {
    console.log('wx.checkSession failed:', res);
    },
    complete: () => {
    wx.login({
    success: (res) => {
    console.log('wx.login success:', res);
    // 登录自有系统
    API.login.wechat({
    js_code: res.code
    }, d => {
    console.log('private login response:', d);
    if (d.code === 0) {
    console.log('private login success:', d);

    let viewerId = d.data.user.user_id;
    _m.globalData.viewerId = viewerId;

    wx.setStorageSync('user_id', viewerId);

    callback && callback();
    } else {
    console.error('get user_id error');
    }
    }, {
    ignoreError: true
    });
    },
    fail: (res) => {
    console.log('wx.login failed:', res);
    }
    });
    }
    });

    三、完整登录代码示例

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    const CONFIG = require('./config.js')
    App({
    globalData:{
    viewerId:null,
    userInfo:null
    大专栏  小程序之登录 },
    onLaunch(){
    // 注册当前用户
    this.register()
    },
    login: function(callback) {
    let _m = this

    // 开发环境重复使用就好
    if (!viewerId && CONFIG.IS_DEBUG) {
    viewerId = wx.getStorageSync('user_id');
    }

    // 先检查是否有登录态,且获取过用户数据;否则触发一次登录
    if (viewerId) {
    _m.globalData.viewerId = viewerId;
    callback && callback();
    } else {
    wx.checkSession({
    success: (res) => {
    console.log('warning wx.checkSession OK, but no viewerId', res);
    },
    fail: (res) => {
    console.log('wx.checkSession failed:', res);
    },
    complete: () => {
    wx.login({
    success: (res) => {
    console.log('wx.login success:', res);
    // 登录自有系统
    API.login.wechat({
    js_code: res.code
    }, d => {
    console.log('private login response:', d);
    if (d.code === 0) {
    console.log('private login success:', d);

    let viewerId = d.data.user.user_id;
    _m.globalData.viewerId = viewerId;

    wx.setStorageSync('user_id', viewerId);

    callback && callback();
    } else {
    console.error('get user_id error');
    }
    }, {
    ignoreError: true
    });
    },
    fail: (res) => {
    console.log('wx.login failed:', res);
    }
    });
    }
    });
    }
    },
    register: function(needTry, callback){
    !callback && (callback = function(){});

    this.login(()=>{
    // 如果曾经授权过,则不用再请求了
    /*try {
    let registedTime = wx.getStorageSync('REGISTED.'+ this.globalData.viewerId);
    // 7天内授权过的不再请求,不再更新资料
    if (registedTime && ((new Date).getTime()-registedTime) < 604800000) {
    callback();
    return;
    }
    } catch (e) {}*/

    wx.getUserInfo({
    success: (res) => {
    let params = {};

    this.globalData.userInfo = res.userInfo;
    params.owner = {
    id: this.globalData.viewerId,

    connected_profile: {
    nickname : res.userInfo.nickName||'', // 用户昵称
    profile_pic_url: res.userInfo.avatarUrl||'', // 头像, avatarUrl
    language : res.userInfo.language||'', // 语言, "zh_TW"
    gender : res.userInfo.gender,
    geo: {
    country : res.userInfo.country,
    province: res.userInfo.province,
    city : res.userInfo.city
    }
    }
    }
    API.profile.update(params, (d) => {
    // 静默注册
    if(d.code === 0) {
    try {
    wx.setStorageSync('USERINFO.'+ this.globalData.viewerId, this.globalData.userInfo);
    wx.setStorageSync('REGISTED.'+ this.globalData.viewerId, (new Date).getTime());
    } catch (e) {}

    callback();
    }
    }, {
    ignoreError: true
    });
    },
    fail: () => {
    console.log('get user info failed: not authorized.', arguments);

    // 强制弹一次授权
    if (needTry) {
    wx.openSetting({
    success: (res)=> {
    if (res.authSetting['scope.userInfo']) {
    wx.showToast({
    title: LANG.AuthorizeSuccess,
    duration: CONFIG.SHOWTOAST_DURATION,
    });
    }
    },
    fail: (res)=> {
    console.log('user not permit to authorize.', arguments);
    }
    });
    }
    },
    withCredentials: false // 不包含openid 等敏感信息
    });
    });
    },
    init: function(callback) {
    this.login(()=>{
    // 塞入常规环境数据
    let pageInstance = this.getCurrentPageInstance(),
    context, screenWidth, screenHeight;

    /*if (this.globalData.device.system_info) {
    screenWidth = this.globalData.device.system_info.screen_width;
    screenHeight = this.globalData.device.system_info.screen_height;
    } else {
    let systemInfo = wx.getSystemInfoSync();
    if (systemInfo) {
    screenWidth = systemInfo.screenWidth;
    screenHeight = systemInfo.screenHeight;
    }
    }*/
    context = {
    LANG : LANG,
    CDN : CONFIG.CDN_HOST,
    isNoContent : false,
    HashtagType : CONFIG.HashtagType,
    VerbType : CONFIG.VerbType,
    GridImageWidthMode : CONFIG.GridImageWidthMode,
    STICKER_MAKER_ENABLED: CONFIG.STICKER_MAKER_ENABLED,
    UGC_ENABLED : CONFIG.UGC_ENABLED,
    UGC_IMAGE_COUNT_LIMIT: CONFIG.UGC_IMAGE_COUNT_LIMIT,
    ReviewStateText : CONFIG.ReviewStateText,

    networkType : this.globalData.device.network ? this.globalData.device.network.network_type : NetworkType.UNKNOWN,

    IS_DEV : CONFIG.IS_DEV,
    IS_SHOW_CONSOLE : CONFIG.IS_SHOW_CONSOLE,
    DEBUG_DATA : [],

    // 全部配置都放开读
    CONFIG : CONFIG,

    videoPlayStatus : {},

    CURRENT_PAGE : pageInstance.data.PAGE,

    hideVideo : false, // 因为小程序中video不能被任何元素遮挡,所以增加此变量,用于一些浮层展示时,隐藏视频

    updated_time : (new Date).getTime() // 页面上次更新时间
    };

    pageInstance.setData({
    context: context
    });

    this.sendLaunchEvent();

    callback && callback();
    })
    }
    })
  • 相关阅读:
    开通博客开心
    Kubernetes/K8s架构师实战集训营【中、高级班】-2020
    Kubernetes/K8s CKA认证全套实训视频教程下载
    centos7安装部署docker
    模拟器genymotion的安装与配置
    工欲善其事必先利其器---Android开发环境搭建
    监控利器---Zabbix(一)
    进击python第4篇:初探模块
    fuser命令小结
    进击python第三篇:基础
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12389250.html
Copyright © 2011-2022 走看看