• <span id="cz2q2"><del id="cz2q2"></del></span>
      <li id="cz2q2"></li><address id="cz2q2"></address>

      1. 新闻?#34892;?Case获取更多行业信息

        当前位置:主页 > 新闻资讯 > 行业新闻 >

        java实现微信小程序登录态维护

        日期:2017-10-08 / 人气:

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

            本次就从最基本的微信小程序登录态维护开?#21450;傘?#23567;程序官方api文?#36947;?#38754;有对登录态的一个完整的解释,并且有相关的代码。想看详情,可以出门右转:https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxloginobject?#19994;?#19968;次看的时候没怎么看懂,并且代码没有提供java版本的,这让一个java程序员情?#25105;?#22570;,所以在努力研究了?#38498;?#20915;定要做一个java版本的简单的demo放出来。

            作为服务端,如果想获得到使用微信小程序的会员信息,就需要小程序作为客户端把会员的基本信息传过来。类似于手机号,openId可以作为当前小程序中?#27809;?#30340;唯一?#21592;?#24535;。?#27426;?#22914;果把会员的openId信息明文直接在服务端与小程序端来回传输的话,会有安全性的问题。万一被别人得到这个openId,就相当于得?#20132;?#21592;的手机号一样,就可以做一些其他操作了,显然是不安全的。

            为了解决这一问题微信采用了相对安全的方式。

         
        
        				
        1. //app.js
        2. App({
        3. onLaunch: function() {
        4. wx.login({
        5. success: function(res) {
        6. if (res.code) {
        7. //发起网络请求
        8. wx.request({
        9. url: 'https://test.com/onLogin',
        10. data: {
        11. code: res.code
        12. }
        13. })
        14. } else {
        15. console.log('获取?#27809;?#30331;录态失败!' + res.errMsg)
        16. }
        17. }
        18. });
        19. }
        20. })

        微信小程序端会调用wx.login的api,然后会得到一个code,这个code对外人来讲是没有任?#25105;?#20041;的,可以放心的传给服务端。服务端得到code?#38498;螅?#21152;上你申请小程序时的appId, app secret,去调微信的接口

        https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code  就可以得到以下?#38382;?/p>

        openid ?#27809;?#21807;一标识  session_key 会话密钥  unionid 本字段在满足一定条件的情况下才返回  其中openid 就是会员的唯一?#21592;?#35760;,此时服务端可以保存下来。  session_key ?#38498;?#35299;密 unionId(整个开?#29260;?#21488;会员的唯一?#21592;?#35782;)时有用。

            服务端得到openid?#38498;螅?#20026;了后边的交互,要保存下来。一般来讲有两种方式:一种是直接入数据库,一种是采用效率高一点的缓存。楼主采用的是后者,方式是redis。

            按照微信的建议此时需要生成一个不重复值作为openId的唯一?#21592;?#35782;。这里采用的是java的uuid。然后把这个uuid值作为key,把openid以及后面会用到的session_key作为value,存进redis。并且把uuid值返回给小程序。这样小程序就可以直接拿uuid值跟服务端交互。

            也许会有人问,如果有人得到uuid值其实跟得到openid没什么区别啊,都相当于是会员的唯一?#21592;?#24535;。

            所以这里要对这个uuid?#21040;?#34892;一个处理。首先存入redis时要有时效性。session_key在微信服务器?#34892;?#26399;是30天,建议服务端缓存session_key不超过30天。当小程序传过来的uuid值过期时,认为这是过期的uuid,则重新走wx.login步骤。

            为了方便redis中不仅会寸uuid与openid的对应关系。还会再存一条openid对应uuid的记录,目的是为了下一次重新wx.login步骤时根据openid?#19994;?#20043;前老的uuid,如果存在的话就删掉,然后查询一条新的uuid值,并且把openid对应的这条记录也更新掉。这样redis服务器中就不会有多余的脏数据,减轻服务器的负担。

            以上就是我理解的整个登录态的过程,当然还有wx.checkSession这些没有讲到,其实就是发现session_key失效是再重新走一遍上述的流程就可以了。所以没有仔细说。不知道我有没有讲清楚。?#19968;?#25226;整个流程的关键代码贴出来,供大家参考。

         
        
        				
        1. @ActionKey("/loginByWeixin")
        2. public void loginByWeixin() throws Exception {
        3. logger.info("Start getSessionKey");
        4. String json = HttpKit.readData(getRequest());
        5. JSONObject reqJson = JSON.parseObject(json);
        6. String jsCode = reqJson.getString("code");
        7. if (jsCode == null || "".equals(jsCode)) {
        8. logger.info("缺少必要?#38382;?quot;);
        9. renderJson(new OutRoot().setCode("100").setMsg(SYS.PARAMETER_FAIL));
        10. } else {
        11. List<Record> record = appInfoService.selectAppInfo();
        12. String appId = record.get(0).get("app_id");
        13. String appSecret = record.get(0).getStr("app_secret");
        14. if (appId == null || "".equals(appId) || appSecret == null || "".equals(appSecret)) {
        15. logger.info("缺少必要?#38382;?quot;);
        16. renderJson(new OutRoot().setCode("100").setMsg(SYS.PARAMETER_FAIL));
        17. } else {
        18. String url = "https://api.weixin.qq.com/sns/jscode2session";
        19. String httpUrl = url + "?appid=" + appId + "&secret=" + appSecret + "&js_code=" + jsCode
        20. + "&grant_type=authorization_code";
        21. String ret = HttpRequest.sendGetRequest(httpUrl);
        22. logger.info("微信返回的结果 {}", ret);
        23. if (ret == null || "".equals(ret)) {
        24. logger.info("网络超时");
        25. renderJson(new OutRoot().setCode("101").setMsg(SYS.CONTACT_FAIL));
        26. } else {
        27. JSONObject obj = JSONObject.parseObject(ret);
        28. if (obj.containsKey("errcode")) {
        29. String errcode = obj.get("errcode").toString();
        30. logger.info("微信返回的错误码{}", errcode);
        31. renderJson(new OutRoot().setCode("101").setMsg(SYS.CONTACT_FAIL));
        32. } else if (obj.containsKey("session_key")) {
        33. logger.info("调微信成功");
        34. // 开始处理userInfo
        35. String openId = obj.get("openid").toString();
        36. Record tbMember = new Record();
        37. tbMember.set("weixin_openid", openId);
        38. System.out.println("openId==" + openId);
        39. // 先查询openId存在不存在,存在不入库,不存在就入库
        40. List<Record> memberList = tbMemberService.selectMember(tbMember);
        41. if (memberList != null && memberList.size() > 0) {
        42. logger.info("openId已经存在,不需要插入");
        43. } else {
        44. JSONObject rawDataJson = reqJson.getJSONObject("userInfo");
        45. String nickName = rawDataJson.getString("nickName");
        46. String avatarUrl = rawDataJson.getString("avatarUrl");
        47. String gender = rawDataJson.getString("gender");
        48. String province = rawDataJson.getString("province");
        49. String city = rawDataJson.getString("city");
        50. String country = rawDataJson.getString("country");
        51. tbMember.set("gender", gender);
        52. tbMember.set("nick_name", nickName);
        53. tbMember.set("avatar_url", avatarUrl);
        54. Long openId2 = tbMemberService.addMember(tbMember);
        55. logger.info("openId不存在,插入数据库");
        56. }
        57. // (1) 获得sessionkey
        58. String sessionKey = obj.get("session_key").toString();
        59. logger.info("sessionKey==" + sessionKey);
        60. logger.info("openId==" + openId);
        61. // (2) 得到sessionkey?#38498;?#23384;?#20132;?#23384;,key值采用不会重复的uuid
        62. String rsession = UUID.randomUUID().toString();
        63. Cache tokenCache = Redis.use("redis_00");
        64. // (3) 首先根据openId,取出来之前存的openId对应的sessionKey的值。
        65. String oldSeesionKey = tokenCache.getJedis().get(openId);
        66. if (oldSeesionKey != null && !"".equals(oldSeesionKey)) {
        67. logger.info("oldSeesionKey==" + oldSeesionKey);
        68. // (4) 删除之前openId对应的缓存
        69. tokenCache.getJedis().del(oldSeesionKey);
        70. logger.info("老的openId删除?#38498;?=" + tokenCache.getJedis().get(oldSeesionKey));
        71. }
        72. // (5) 开始缓存新的sessionKey: key --> uuid, value --> sessionObj
        73. JSONObject sessionObj = new JSONObject();
        74. sessionObj.put("openId", openId);
        75. sessionObj.put("sessionKey", sessionKey);
        76. tokenCache.getJedis().set(rsession, sessionObj.toJSONString());
        77.  
        78. // (6) 开始缓存新的openId与session对应关系 : key --> openId , value --> rsession
        79. tokenCache.getJedis().set(openId, rsession);
        80.  
        81. String newOpenId = tokenCache.getJedis().get(openId);
        82. String newrSession = tokenCache.getJedis().get(rsession);
        83. logger.info("新的openId==" + newOpenId);
        84. logger.info("新的newrSession==" + newrSession);
        85. // (7) 把新的sessionKey返回给小程序
        86. JSONObject objret = new JSONObject();
        87. objret.put("rdSessionKey", rsession);
        88. objret.put("errno", 0);
        89. renderJson(objret);
        90. }
        91.  
        92. }
        93. }
        94. }
        95. }

            项目框架是我比较?#19981;禞final,java轻?#32771;都?#36895;开发框架,非常高效,也推荐给大家。可能有哪些遗漏的地?#20132;?#36814;大?#19968;?#26497;提出意见和批评。

        我是一名java开发者,?#19981;?#30740;究一些新的技术,体验一些新的产品,如果?#19981;?#36825;篇文章,也希望能转发一下。请注明一下出去就可以了。如果哪里不懂,也可以留言,或者加一下?#19994;?#20010;人微信,也希望能交更多的朋友。深圳市灵点网络科技有限公司是一家专业互联网品牌营销顾问机构。专业致力于最前沿的互联网技术开发和互联网营销策划服务内容涉及企业互联网咨询、深圳网站建设深圳网站制作深圳网站设计网页制作、企业形象设计、包装画册设计、Flash多媒体设计与制作。


        编辑:深圳网站建设公司


        ?
        澳博线上官网

      2. <span id="cz2q2"><del id="cz2q2"></del></span>
          <li id="cz2q2"></li><address id="cz2q2"></address>

          1. <span id="cz2q2"><del id="cz2q2"></del></span>
              <li id="cz2q2"></li><address id="cz2q2"></address>