小程序登录分享留资
kingcwt2018-09-20前端小程序
一、介绍
小程序实现微信登录
,获取手机号
,转发分享
,以及留资
功能
二、参考
2.1、首先点击免费领取 获取用户信息并拿到用户的手机号留资分为两个步骤
2.2、微信小程序登录文档链接
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
2.3、微信小程序获取手机号文档链接
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
三、前端代码
3.1、wxml 部分
<block>
<text wx:if="{{phoneNumber}}">恭喜:{{phoneNumber}}用户 领取成功!</text>
<button
class="sbtn"
wx:else
open-type="getPhoneNumber"
bindgetphonenumber="getPhoneNumber"
>
免费领取
</button>
</block>
3.2、分享
//在onLoad中调用
wx.showShareMenu({
withShareTicket: true,
menus: ["shareAppMessage", "shareTimeline"],
});
onShareAppMessage: function () {
console.log('转发')
return {
title: '转发吧',
imageUrl: "../../img/headerimg.jpeg",
success(e) {
withShareTicket: true
},
fail(e) {
}
}
},
3.3、调用接口获取登录凭证(code)
参考
//在onLoad中调用
wx.login({
success(res) {
console.log("临时登录凭证code", res.code);
wx.request({
url: "http://127.0.0.1:3008/login/wxk",
method: "post",
data: { code: res.code },
success(res) {
console.log("换取 用户唯一标识 OpenID 和 会话密钥 session_key", res);
wx.setStorage({ key: "id", data: res.data.id });
},
err(err) {
console.log(err, "no");
},
});
},
fail: function(err) {
console.log(err, "err");
},
});
3.4、获取手机号并留资
//获取手机号
getPhoneNumber: function (e) {
var _this = this;
wx.getStorage({
key: 'id',
success(res) {
console.log(res.data)
wx.request({
url: 'http://127.0.0.1:3008/login/phone',
method: 'post',
data: { openid: res.data, encryptedData: e.detail.encryptedData, iv: e.detail.iv },
success(res) {
//留资func
_this.enterXiaoyun(res.data.data.phoneNumber, '童程童美', 'jtlgkfk1', res.data.data.watermark.appid)
_this.setData({
phoneNumber: res.data.data.phoneNumber
})
},
err(err) {
console.log(err, 'no')
}
})
}
})
}
//留资func
enterXiaoyun: function (mob, tag, id, appid) {
var _this = this;
var data = {
flnm: appid,
mob: mob,
tags: [`${tag}`],
utm_source: null,
utm_medium: null,
id: new Date().getTime()
};
wx.request({
url: 'https://landingpage.xiaoyun.com/landings/push/landpage/entry/' + id,
method: 'POST',
data: data,
success(res) {
console.log('enterxy - success')
_this.showSuccessModal()
},
fail(err) {
console.log('enterxy - err')
}
})
},
3.5、完整代码(index.js)
//index.js
//获取应用实例
const app = getApp();
Page({
data: {
motto: "Hello World",
userInfo: {},
hasUserInfo: false,
canIUse: wx.canIUse("button.open-type.getUserInfo"),
phoneNumber: null,
},
//事件处理函数
bindViewTap: function() {
wx.navigateTo({
url: "../logs/logs",
});
},
onLoad: function() {
wx.showShareMenu({
withShareTicket: true,
menus: ["shareAppMessage", "shareTimeline"],
});
wx.login({
success(res) {
console.log(res, "sss");
wx.request({
url: "http://127.0.0.1:3008/login/wxk",
// url: 'http://www.kingcwt.top:3008/login/wxk',
method: "post",
data: { code: res.code },
success(res) {
console.log(res, "ok");
wx.setStorage({ key: "id", data: res.data.id });
},
err(err) {
console.log(err, "no");
},
});
},
fail: function(err) {
console.log(err, "err");
},
});
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,
});
},
});
}
},
//转发
onShareAppMessage: function() {
console.log("转发");
return {
title: "转发吧",
imageUrl: "../../img/headerimg.jpeg",
success(e) {
withShareTicket: true;
},
fail(e) {},
};
},
//#留资成功提示
showSuccessModal: function() {
wx.showToast({
title: "领取成功",
icon: "success",
duration: 2000,
});
},
//#留资到小云平台
enterXiaoyun: function(mob, tag, id, appid) {
var _this = this;
var data = {
flnm: appid,
mob: mob,
tags: [`${tag}`],
utm_source: null,
utm_medium: null,
id: new Date().getTime(),
};
wx.request({
url: "https://landingpage.xiaoyun.com/landings/push/landpage/entry/" + id,
method: "POST",
data: data,
success(res) {
console.log("enterxy - success");
_this.showSuccessModal();
},
fail(err) {
console.log("enterxy - err");
},
});
},
//# 一键获取手机号码
getPhoneNumber: function(e) {
var _this = this;
wx.getStorage({
key: "id",
success(res) {
console.log(res.data);
wx.request({
url: "http://127.0.0.1:3008/login/phone",
// url: 'http://www.kingcwt.top:3008/login/phone',
method: "post",
data: {
openid: res.data,
encryptedData: e.detail.encryptedData,
iv: e.detail.iv,
},
success(res) {
console.log(res.data.data.watermark.appid, "ok - phone");
_this.enterXiaoyun(
res.data.data.phoneNumber,
"童程童美",
"jtlgkfk1",
res.data.data.watermark.appid
);
_this.setData({
phoneNumber: res.data.data.phoneNumber,
});
},
err(err) {
console.log(err, "no");
},
});
},
});
},
});
四、后段代码
4.1、路由(router.js)
//微信用户登录获取key
{
method: 'POST',
path: '/login/wxk',
handler: xy.loginCodeAPI,
options: {
auth: false,
description: '微信用户登录获取key',
tags: ['api'],
}
},
//微信用户登录手机
{
method: 'POST',
path: '/login/phone',
handler: xy.loginInfoAPI,
options: {
auth: false,
description: '微信用户登录手机',
tags: ['api'],
}
}
4.2、handler
//微信用户登录获取key
exports.loginCodeAPI = async (req, h) => {
console.log("on");
const { code } = req.payload;
let data = await axios
.get(
`https://api.weixin.qq.com/sns/jscode2session?appid={小程序appid}&secret={小程序secret}&js_code=${code}&grant_type=authorization_code`
)
.then((res) => {
return res.data;
});
console.log(data, "返回的key");
const f = await tao.WXUserKey.findOne({ openid: data.openid });
if (f) {
const WXUserKey = await tao.WXUserKey.updateOne(
{ openid: data.openid },
data
);
} else {
const c = await tao.WXUserKey.create(data);
}
return { code: 1, msg: "ok", id: data.openid };
};
//微信用户登录手机
exports.loginInfoAPI = async (req, h) => {
const { openid, encryptedData, iv } = req.payload;
console.log(openid, encryptedData, iv, "fffffff---");
const a = await tao.WXUserKey.findOne({ openid });
console.log(a, "????-");
console.log(a.openid, "-", a.session_key);
const pc = new WXBizDataCrypt(a.openid, a.session_key);
console.log(pc, "lll");
let data = pc.decryptData(encryptedData, iv);
if (data) {
return { code: 1, msg: "phone", data };
}
console.log("解密后 data: ", data);
const f = await tao.WXUserInfo.findOne({ openid });
if (!f) {
const c = await tao.WXUserInfo.create({
openId: data.openId,
nickName: data.nickName,
gender: data.gender,
language: data.language,
city: data.city,
province: data.province,
country: data.country,
avatarUrl: data.avatarUrl,
});
return { code: 1, msg: "ok1", data };
}
const d = await tao.WXUserInfo.update(
{ openid },
{
openId: data.openId,
nickName: data.nickName,
gender: data.gender,
language: data.language,
city: data.city,
province: data.province,
country: data.country,
avatarUrl: data.avatarUrl,
}
);
console.log(d, "pppp");
return { code: 1, msg: "ok", data };
};
4.3、WXBizDataCrypt
var crypto = require("crypto");
function WXBizDataCrypt(appId, sessionKey) {
this.appId = appId;
this.sessionKey = sessionKey;
}
WXBizDataCrypt.prototype.decryptData = function(encryptedData, iv) {
// base64 decode
var sessionKey = Buffer.from(this.sessionKey, "base64");
encryptedData = Buffer.from(encryptedData, "base64");
iv = Buffer.from(iv, "base64");
try {
// 解密
var decipher = crypto.createDecipheriv("aes-128-cbc", sessionKey, iv);
// 设置自动 padding 为 true,删除填充补位
decipher.setAutoPadding(true);
var decoded = decipher.update(encryptedData, "binary", "utf8");
console.log(decipher, "look");
decoded += decipher.final("utf8");
console.log(decoded, "???");
decoded = JSON.parse(decoded);
console.log(decoded, "HHHHH");
return decoded;
} catch (err) {
throw new Error("Illegal Buffer");
}
if (decoded.watermark.appid !== this.appId) {
throw new Error("Illegal Buffer");
}
return decoded;
};
module.exports = WXBizDataCrypt;