小程序-授权登录

4,494 阅读4分钟

1、注意

现在的微信小程序必须用户去手动授权才能够进行授权登录,而不能在页面加载的时候进行授权。

开发者必须在页面中手动添加一个button按钮

2、获取code

利用button按钮唤起授权弹框

参考developers.weixin.qq.com/miniprogram…

<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">授权登录</button>
<text bindtap="getUserInfo">授权登录(不加button)</text>
 
getUserInfo: function() {
         wx.login({
            success (res){
                if(res.code) {
                    console.log(res.code);
                }
            }
        })
    },

上面两个按钮,第一个能唤起授权登录弹框,第二个无法获取,开发时采用第一个

3、利用wx.canIUse判断小程序的API,回调,参数,组件等是否在当前版本可用。

讲上述代码改为

<!-- 需要使用 button 来授权登录 -->
<button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">授权登录</button>
<view wx:else>请升级微信版本</view>
 
// 在data中定义
data: {
    canIUse: wx.canIUse('button.open-type.getUserInfo')
},

4、判断是否有用户信息

button按钮中绑定的方法 bindGetUserInfo ,当通过授权后就能够获取用户的微信昵称、头像地址、性别、地区等


方法定义

bindGetUserInfo: function(e) {
    console.log(e.detail.userInfo)
},

5、结合login方法进行code获取

bindGetUserInfo: function(e) {
    console.log(e.detail.userInfo)
    if(e.detail.userInfo) {
        wx.login({
            success (res){
                if(res.code) {
                    console.log(res.code);
                }
            }
        })
    }
},

6、根据code获取openId或者unionid

根据auth.code2Session进行登录凭证校验,这里一般是将这里的jscode2session接口在后台进行封装后转发到小程序端进行调用。

需要注意的两点

会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。 临时登录凭证 code 只能使用一次 所以该接口应封在后台

接口请求地址
GET api.weixin.qq.com/sns/jscode2…

请求参数
属性 类型 必填 说明
appid string 小程序 appId
secret string 小程序 appSecret
js_code string 登录时获取的 code
grant_type string 授权类型,此处只需填写 authorization_code
返回值

返回JSON数据包

属性 类型 说明
openid string 用户唯一标识
session_key string 会话密钥
unionid string 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见 UnionID 机制说明。
errcode string 错误码
errmsg string 错误信息
errcode 的合法值
说明
-1 系统繁忙,此时请开发者稍候再试
0 请求成功
40029 code 无效
45011 频率限制,每个用户每分钟100次

将改接口引入到 login 方法中

bindGetUserInfo: function(e) {
    console.log(e.detail.userInfo)
    if(e.detail.userInfo) {
        wx.login({
            success (res){
                if(res.code) {
                    console.log(res.code);
                    wx.request({
                        url: "https://api.weixin.qq.com/sns/jscode2session",
                        data: {
                            appid: app.globalData.appid,
                            secret: app.globalData.secret,
                            js_code: res.code,
                            grant_type: "authorization_code"
                        },
                        success: function(response) {
                            console.log(response);
                            wx.setStorageSync("miniOpenId",response.data.openid);
                        }
                    })
                }
            }
        })
    }
},

我这边是直接请求官方给的jscode2session接口,实际开发中将此处的调用换为封装的接口,appid,secret我统一放置在app.js中,以 globalData 进行存储

7、判断用户是否授权

考虑到用户可能会点击到拒绝按钮,点击授权拒绝按钮后,该授权弹框无法唤起,必须得对用户是否授权进行判断

此时需要用 wx.getSetting 方法来获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。

此方法具体的参数及配置参考官方文档 developers.weixin.qq.com/miniprogram…

如果用户授权通过,改接口的返回值 authSetting 会有 scope.userInfo

若已授权,可以通过 wx.getUserInfo 返回用户的用户信息

如若未授权,可以手动定义一个弹框引导用户去进行授权登录,这个弹框的内容一定得加上上述提到得那个 按钮 <button open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">授权登录</button>

加上一个参数 modelShow 管理显隐

wx.getSetting({
        success (res){
            if (res.authSetting['scope.userInfo']) {
                // 已经授权,可以直接调用 getUserInfo 获取头像昵称
                wx.getUserInfo({
                    success: function(res) {
                        console.log(res.userInfo)
                    }
                })
            }
 
                // 这边的判断是根据用户如果没有进行授权登录,进行一个自定义弹框的显隐
                if (!res.authSetting['scope.userInfo']) {
                    _this.setData({
                        modelShow: true
                    })
                } else {
                    _this.setData({
                        modelShow: false
                    })
                }
        }
    })

此方法需单独定义一个函数,可以在进行某一些操作之前判断是否进行过授权登录

我一般会在页面加载 onLoad 中进行一些关于授权登录之后参数的判断和保存

onLoad: function () {
    if (app.globalData.userInfo) {
        this.setData({
            userInfo: app.globalData.userInfo,
            hasUserInfo: true
        })
    } else if (this.data.canIUse){
        // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
        // 所以此处加入 callback 以防止这种情况
        app.userInfoReadyCallback = res => {
            this.setData({
                userInfo: res.userInfo,
                hasUserInfo: true
            })
        }
    } else {
        // 在没有 open-type=getUserInfo 版本的兼容处理
        wx.getUserInfo({
            success: res => {
                app.globalData.userInfo = res.userInfo
                this.setData({
                    userInfo: res.userInfo,
                    hasUserInfo: true
                })
            }
        })
    }
},