相信不少喜欢开发的朋友都已经知道微信小程序是个什么物种了,楼主也是从小程序内测期间就开始关注,并且也写过几个已经上线的微信小程序。但是基本上都是写的纯前端,最近楼主从后端到前端写一个完整的小程序项目,中间碰到了一些问题,楼主会找一些个人觉得有学习价值的点不定时的拿出来跟大家分享,希望对你有一些帮助。

本次就从最基本的微信小程序登录态维护开始吧。小程序官方api文档里面有对登录态的一个完整的解释,并且有相关的代码。想看详情,可以出门右转:https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxloginobject 我第一次看的时候没怎么看懂,并且代码没有提供java版本的,这让一个java程序员情何以堪,所以在努力研究了以后决定要做一个java版本的简单的demo放出来。
作为服务端,如果想获得到使用微信小程序的会员信息,就需要小程序作为客户端把会员的基本信息传过来。类似于手机号,openId可以作为当前小程序中用户的唯一性标志。然而如果把会员的openId信息明文直接在服务端与小程序端来回传输的话,会有安全性的问题。万一被别人得到这个openId,就相当于得到会员的手机号一样,就可以做一些其他操作了,显然是不安全的。
为了解决这一问题微信采用了相对安全的方式。
//app.js
App({
onLaunch: function() {
wx.login({
success: function(res) {
if (res.code) {
//发起网络请求
wx.request({
url: 'https://test.com/onLogin',
data: {
code: res.code
}
})
} else {
console.log('获取用户登录态失败!' + res.errMsg)
}
}
});
}
})
微信小程序端会调用wx.login的api,然后会得到一个code,这个code对外人来讲是没有任何意义的,可以放心的传给服务端。服务端得到code以后,加上你申请小程序时的appId, app secret,去调微信的接口
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
就可以得到以下参数:
其中openid 就是会员的唯一性标记,此时服务端可以保存下来。
session_key 以后解密 unionId(整个开放平台会员的唯一性标识)时有用。
服务端得到openid以后,为了后边的交互,要保存下来。一般来讲有两种方式:一种是直接入数据库,一种是采用效率高一点的缓存。楼主采用的是后者,方式是redis。
按照微信的建议此时需要生成一个不重复值作为openId的唯一性标识。这里采用的是java的uuid。然后把这个uuid值作为key,把openid以及后面会用到的session_key作为value,存进redis。并且把uuid值返回给小程序。这样小程序就可以直接拿uuid值跟服务端交互。
也许会有人问,如果有人得到uuid值其实跟得到openid没什么区别啊,都相当于是会员的唯一性标志。
所以这里要对这个uuid值进行一个处理。首先存入redis时要有时效性。session_key在微信服务器有效期是30天,建议服务端缓存session_key不超过30天。当小程序传过来的uuid值过期时,认为这是过期的uuid,则重新走wx.login步骤。
为了方便redis中不仅会寸uuid与openid的对应关系。还会再存一条openid对应uuid的记录,目的是为了下一次重新wx.login步骤时根据openid找到之前老的uuid,如果存在的话就删掉,然后查询一条新的uuid值,并且把openid对应的这条记录也更新掉。这样redis服务器中就不会有多余的脏数据,减轻服务器的负担。
以上就是我理解的整个登录态的过程,当然还有wx.checkSession这些没有讲到,其实就是发现session_key失效是再重新走一遍上述的流程就可以了。所以没有仔细说。不知道我有没有讲清楚。我会把整个流程的关键代码贴出来,供大家参考。
@ActionKey("/loginByWeixin")
public void loginByWeixin() throws Exception {
logger.info("Start getSessionKey");
String json = HttpKit.readData(getRequest());
JSONObject reqJson = JSON.parseObject(json);
String jsCode = reqJson.getString("code");
if (jsCode == null || "".equals(jsCode)) {
logger.info("缺少必要参数");
renderJson(new OutRoot().setCode("100").setMsg(SYS.PARAMETER_FAIL));
} else {
List<Record> record = appInfoService.selectAppInfo();
String appId = record.get(0).get("app_id");
String appSecret = record.get(0).getStr("app_secret");
if (appId == null || "".equals(appId) || appSecret == null || "".equals(appSecret)) {
logger.info("缺少必要参数");
renderJson(new OutRoot().setCode("100").setMsg(SYS.PARAMETER_FAIL));
} else {
String url = "https://api.weixin.qq.com/sns/jscode2session";
String httpUrl = url + "?appid=" + appId + "&secret=" + appSecret + "&js_code=" + jsCode
+ "&grant_type=authorization_code";
String ret = HttpRequest.sendGetRequest(httpUrl);
logger.info("微信返回的结果 {}", ret);
if (ret == null || "".equals(ret)) {
logger.info("网络超时");
renderJson(new OutRoot().setCode("101").setMsg(SYS.CONTACT_FAIL));
} else {
JSONObject obj = JSONObject.parseObject(ret);
if (obj.containsKey("errcode")) {
String errcode = obj.get("errcode").toString();
logger.info("微信返回的错误码{}", errcode);
renderJson(new OutRoot().setCode("101").setMsg(SYS.CONTACT_FAIL));
} else if (obj.containsKey("session_key")) {
logger.info("调微信成功");
// 开始处理userInfo
String openId = obj.get("openid").toString();
Record tbMember = new Record();
tbMember.set("weixin_openid", openId);
System.out.println("openId==" + openId);
// 先查询openId存在不存在,存在不入库,不存在就入库
List<Record> memberList = tbMemberService.selectMember(tbMember);
if (memberList != null && memberList.size() > 0) {
logger.info("openId已经存在,不需要插入");
} else {
JSONObject rawDataJson = reqJson.getJSONObject("userInfo");
String nickName = rawDataJson.getString("nickName");
String avatarUrl = rawDataJson.getString("avatarUrl");
String gender = rawDataJson.getString("gender");
String province = rawDataJson.getString("province");
String city = rawDataJson.getString("city");
String country = rawDataJson.getString("country");
tbMember.set("gender", gender);
tbMember.set("nick_name", nickName);
tbMember.set("avatar_url", avatarUrl);
Long openId2 = tbMemberService.addMember(tbMember);
logger.info("openId不存在,插入数据库");
}
// (1) 获得sessionkey
String sessionKey = obj.get("session_key").toString();
logger.info("sessionKey==" + sessionKey);
logger.info("openId==" + openId);
// (2) 得到sessionkey以后存到缓存,key值采用不会重复的uuid
String rsession = UUID.randomUUID().toString();
Cache tokenCache = Redis.use("redis_00");
// (3) 首先根据openId,取出来之前存的openId对应的sessionKey的值。
String oldSeesionKey = tokenCache.getJedis().get(openId);
if (oldSeesionKey != null && !"".equals(oldSeesionKey)) {
logger.info("oldSeesionKey==" + oldSeesionKey);
// (4) 删除之前openId对应的缓存
tokenCache.getJedis().del(oldSeesionKey);
logger.info("老的openId删除以后==" + tokenCache.getJedis().get(oldSeesionKey));
}
// (5) 开始缓存新的sessionKey: key --> uuid, value --> sessionObj
JSONObject sessionObj = new JSONObject();
sessionObj.put("openId", openId);
sessionObj.put("sessionKey", sessionKey);
tokenCache.getJedis().set(rsession, sessionObj.toJSONString());
// (6) 开始缓存新的openId与session对应关系 : key --> openId , value --> rsession
tokenCache.getJedis().set(openId, rsession);
String newOpenId = tokenCache.getJedis().get(openId);
String newrSession = tokenCache.getJedis().get(rsession);
logger.info("新的openId==" + newOpenId);
logger.info("新的newrSession==" + newrSession);
// (7) 把新的sessionKey返回给小程序
JSONObject objret = new JSONObject();
objret.put("rdSessionKey", rsession);
objret.put("errno", 0);
renderJson(objret);
}
}
}
}
}
项目框架是我比较喜欢Jfinal,java轻量级急速开发框架,非常高效,也推荐给大家。可能有哪些遗漏的地方欢迎大家积极提出意见和批评。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# 微信小程序
# 登录
# java
# 微信小程序登录态
# Java后端接入微信小程序登录功能(登录流程)
# java实现微信扫码登录第三方网站功能(原理和代码)
# 微信小程序微信登录的实现方法详解(JAVA后台)
# 详解java实现简单扫码登录功能(模仿微信网页版扫码)
# Java中基于Shiro
# JWT实现微信小程序登录完整例子及实现过程
# 使用weixin-java-tools完成微信授权登录、微信支付的示例
# 第三方网站微信登录java代码实现
# java实现 微博登录、微信登录、qq登录实现代码
# Java实现微信登录并获取用户信息功能(开发流程)
# 服务端
# 就可以
# 不存在
# 的是
# 都是
# 这是
# 几个
# 这一
# 是个
# 会有
# 我有
# 不需要
# 没有任何
# 对你
# 一遍
# 作了
# 这条
# 要做
# 采用了
# 推荐给
相关文章:
如何规划企业建站流程的关键步骤?
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
官网自助建站平台指南:在线制作、快速建站与模板选择全解析
非常酷的网站设计制作软件,酷培ai教育官方网站?
开封网站制作公司,网络用语开封是什么意思?
完全自定义免费建站平台:主题模板在线生成一站式服务
如何快速打造个性化非模板自助建站?
子杰智能建站系统|零代码开发与AI生成SEO优化指南
建站之星后台密码遗忘如何找回?
如何通过IIS搭建网站并配置访问权限?
装修招标网站设计制作流程,装修招标流程?
C++时间戳转换成日期时间的步骤和示例代码
广州建站公司哪家好?十大优质服务商推荐
*服务器网站为何频现安全漏洞?
一键网站制作软件,义乌购一件代发流程?
建站VPS选购需注意哪些关键参数?
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
如何在阿里云虚拟服务器快速搭建网站?
建站之星后台密码如何安全设置与找回?
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
上海网站制作网站建设公司,建筑电工证网上查询系统入口?
家庭服务器如何搭建个人网站?
桂林网站制作公司有哪些,桂林马拉松怎么报名?
建站主机类型有哪些?如何正确选型
建站之星代理如何获取技术支持?
个人摄影网站制作流程,摄影爱好者都去什么网站?
电脑免费海报制作网站推荐,招聘海报哪个网站多?
网站制作话术技巧,网站推广做的好怎么话术?
网站制作报价单模板图片,小松挖机官方网站报价?
如何选择香港主机高效搭建外贸独立站?
5种Android数据存储方式汇总
定制建站模板如何实现SEO优化与智能系统配置?18字教程
如何通过商城自助建站源码实现零基础高效建站?
高性能网站服务器配置指南:安全稳定与高效建站核心方案
如何快速上传自定义模板至建站之星?
宝塔新建站点为何无法访问?如何排查?
中山网站制作网页,中山新生登记系统登记流程?
制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?
如何解决ASP生成WAP建站中文乱码问题?
建站主机系统SEO优化与智能配置核心关键词操作指南
c++ stringstream用法详解_c++字符串与数字转换利器
如何在橙子建站中快速调整背景颜色?
如何快速上传建站程序避免常见错误?
南京网站制作费用,南京远驱官方网站?
如何确认建站备案号应放置的具体位置?
简单实现Android验证码
如何选择CMS系统实现快速建站与SEO优化?
建站之星北京办公室:智能建站系统与小程序生成方案解析
视频网站制作教程,怎么样制作优酷网的小视频?
网站设计制作企业有哪些,抖音官网主页怎么设置?
*请认真填写需求信息,我们会在24小时内与您取得联系。