微信小程序登录分析
以下后端代码都是在node egg框架内执行,切勿搞混了,分享的只是登录注册思路,想要编程学的好,就好多动手
按照微信官方给的流程图,我们得知,当小程序需要注册登录时,必须从小程序客户端通过wx.login获取对应的code,发送到后端通过微信官方接口获取唯一的识别码 (openid)
小程序注册的两种方式
第一种
通过手动点击授权登录注册,如果当前用户第一次进入并点击授权,就会先注册在登陆,如果已注册,就直接登录
给点击授权绑定一个名叫login的点击事件,通过bindtap属性绑定<view class="authorization" bindtap="login">点击授权</view>
在登录页面的js文件内 定义一个 login方法,内容如下
login(){
//当用户点击授权时,执行login方法,并且通过wx.getUserProfile开放接口获取到当前用户的信息,
wx.getUserProfile({
desc: '用于用户注册', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
//在成功回调里把返回的userinfo解构出来,并存到本地缓存里,方便后续各个页面显示当前用户的信息,例如“我的”页面会显示用户头像和昵称等,再定义一个userInfo 变量接收下用户资料,后续一起发送到后端
let userInfo = res.userInfo;
wx.setStorageSync('userInfo', userInfo);
this.setData({
userInfo,
hasUserInfo: true
})
console.log(res);
//代码执行到这里时,会执行wx.login这个开放接口获取微信用户的临时凭证
wx.login({
success (res) {
//当wx.login返回结果后把唯一凭证取出来,并存到上面新建的userInfo变量内
userInfo.code = res.code;
//把变量通过post方式传递到后端
axios.post({url: '/wxlogin',data:userInfo})
.then((data)=>{
console.log(data);
wx.setStorageSync('token', data.data.data.token);
}).catch(e=>{
console.log(e);
})
}
})
},
fail:(res)=>{
console.log("授权失败",res);
}
})
},
复制代码
后端部分
在controller层新建一个Weixin.ts,同时定义一个wxAuth的方法用户路由执行该方法,并接收小程序发送来的UserInfo
public async wxAuth(){
const { ctx } = this;
const userInfo = ctx.request.body;
//以下两个需要去微信小程序后台那获取,这两个是开发者的APP相关资料,切勿泄露,以下都是我修改过的,所以展示出来没事,一般放在config里面,这样打包编译就不会泄露出来,如果按照以下写,有心人想要获取很容易获取到
const AppId = 'wxc3e768e332c12f4c';
const AppSecret = '8fb8e48c87e05cec2762518770fd3f09';
//通过 微信开放接口获取openid,这一步应该在service层做的,但是我嫌麻烦就写到controller内了,开发时一定要写到service层
const result = await ctx.curl(`https://api.weixin.qq.com/sns/jscode2session?appid=${AppId}&secret=${AppSecret}&js_code=${userInfo.code}&grant_type=authorization_code`,{
dataType: "json",
timeout: 5000,
method: "GET",
data: JSON.stringify({})
})
if (result.data.errcode === 41008){
throw new Error("缺少code")
}
if (result.data.errcode === 40029){
throw new Error("code 无效")
}
if (result.data.errcode === 45011){
throw new Error("code 频率限制")
}
if (result.data.errcode === -1){
throw new Error("系统繁忙,请稍后再试")
}
if (result.data.errcode === 40163){
throw new Error("当前code已经被使用")
}
/*
* 当请求成功时,会返回如下格式的数据
* "data": {
"session_key": "FSn2szxyuYndSbdowg5Zzw==",
"openid": "o0teF4mqBhpe-pfa01QK4xc3l4c3"
}
* */
//解构出 session_key和openid
// @ts-ignore
const {session_key,openid} = result;
//组装用户数据,把所需的数据保存下来,方便后续创建用户,当然也要看你的表结构,所需什么数据就组装成什么结构,例如我的是用户表和用户信息表分开的,以下user就是存到userinfo这张表里的所需数据
let User = {
opId: openid,
avatarUrl: userInfo.avatarUrl,
userName: userInfo.nickName,
gender: userInfo.gender,
provider: "WeiXin",
accessToken: session_key
}
// 调用同层的gotoAdmin方法并传递User这个变量,在这个方法内决定是否注册或直接登陆
await this.goToAdmin(User)
}
public async goToAdmin(_User){
// const {ctx} = this;
//通过Try和catch判断是否注册和登录
try {
//在Try里面执行service层的用户查询方法,用户存在返回用户信息,如果没有查询到用户,就报错执行catch里面的代码
//下面就是执行你的后端处理登录的逻辑了,例如token的签发,用户信息的返回等
}catch (e) {
// 用户不存在先注册再登陆,例如通过uuid创建用户名等,然后前端传递过来的数据和生成好的用户信息等保存到数据库,再返回数据到小程序
}
}
复制代码
第二种方式
和上面差不多,在小程序入口文件内执行wx.login,当用户一进来就在后台悄悄地给他注册,当用户点击授权按钮时,就把获取的用户资料发送到后端保存起来,两种方法都可以,一种是授权的同时,注册并保存用户资料,一种是先注册,再保存用户资料
近期评论