长此以往怪将不怪 發表於 2020-10-27 00:32:00

uni-app实战 | 第一篇:从0到1快速开发一个开源商城微信小程序,无缝接入Spring Security OAuth2认证授权实现登录

<p><img src="https://i.loli.net/2020/10/25/Ns1Ep6wqyV9MrYx.gif" alt="" loading="lazy"></p>
<h1 id="一-前言">一. 前言</h1>
<p>本篇通过实战来讲述如何使用uni-app快速进行商城微信小程序的开发以及小程序如何接入后台Spring Cloud微服务。</p>
<p>有来商城 youlai-mall 项目是一套全栈商城系统,技术栈是分布式微服务加上前后端分离模式,所以在本篇项目实战开始之前需要一些往期文章作为基础。</p>
<blockquote>
<p>后台微服务</p>
</blockquote>
<ol>
<li>Spring Cloud实战 | 第一篇:Windows搭建Nacos服务 </li>
<li>Spring Cloud实战 | 第二篇:Spring Cloud整合Nacos实现注册中心</li>
<li>Spring Cloud实战 | 第三篇:Spring Cloud整合Nacos实现配置中心</li>
<li>Spring Cloud实战 | 第四篇:Spring Cloud整合Gateway实现API网关</li>
<li>Spring Cloud实战 | 第五篇:Spring Cloud整合OpenFeign实现微服务之间的调用</li>
<li>Spring Cloud实战 | 第六篇:Spring Cloud Gateway+Spring Security OAuth2+JWT实现微服务统一认证授权</li>
<li>Spring Cloud实战 | 最七篇:Spring Cloud Gateway+Spring Security OAuth2集成统一认证授权平台下实现注销使JWT失效方案</li>
<li>Spring Cloud实战 | 最八篇:Spring Cloud +Spring Security OAuth2+ Vue前后端分离模式下无感知刷新实现JWT续期</li>
<li>Spring Cloud实战 | 最九篇:Spring Security OAuth2认证服务器统一认证自定义异常处理</li>
<li>Spring Cloud实战 | 第十篇 :Spring Cloud + Nacos整合Seata 1.4.1最新版本实现微服务架构中的分布式事务,进阶之路必须要迈过的槛</li>
<li>Spring Cloud实战 | 第十一篇 :Spring Cloud Gateway网关实现对RESTful接口权限和按钮权限细粒度控制<br>
</li>
</ol>
<blockquote>
<p>后台管理前端</p>
</blockquote>
<ol>
<li>vue-element-admin实战 | 第一篇: 移除mock接入微服务接口,搭建SpringCloud+Vue前后端分离管理平台</li>
<li>vue-element-admin实战 | 第二篇: 最小改动接入后台实现根据权限动态加载菜单</li>
</ol>
<blockquote>
<p>微信小程序</p>
</blockquote>
<ol>
<li>vue+uni-app商城实战 | 第一篇:从0到1快速开发一个商城微信小程序,无缝接入Spring Cloud OAuth2认证授权登录</li>
</ol>
<blockquote>
<p>应用部署</p>
</blockquote>
<ol>
<li>Docker实战 | 第一篇:Linux 安装 Docker</li>
<li>Docker实战 | 第二篇:Docker部署nacos-server:1.4.0</li>
<li>Docker实战 | 第三篇:IDEA集成Docker插件实现一键自动打包部署微服务项目,一劳永逸的技术手段值得一试</li>
<li>Docker实战 | 第四篇:Docker安装Nginx,实现基于vue-element-admin框架构建的项目线上部署</li>
<li>Docker实战 | 第五篇:Docker启用TLS加密解决暴露2375端口引发的安全漏洞,被黑掉三台云主机的教训总结</li>
</ol>
<h1 id="二-项目介绍">二. 项目介绍</h1>
<h2 id="1-项目简介">1. 项目简介</h2>
<p>有来商城youlai-mall一套全栈的商城系统。整个系统采用微服务架构,前后端分离交互模式。后端采用Spring Boot + Spring Cloud 并使用Spring Cloud Alibaba对微服务进行扩展。管理平台前端采用Vue + Element-UI,基于成熟的后台前端解决方案vue-element-admin。微信小程序端使用uni-app。</p>
<h2 id="2-技术选型">2. 技术选型</h2>
<p>相信一个Java后端开发来说,后端和管理平台前端的技术栈的选取应当毋庸置疑,当前主流。</p>
<p>至于基于vue的微信小程序开发为什么选择uni-app而非像微信原生、mpvue、vant等框架,个人观点不能说不好,只能说组件不丰富的问题对于一个前端半吊子的自己来说是不太友好,更别说快速开发了,直到迷茫的时候遇见了了uni-app这么个神玩意儿,可以说是相见恨晚,后文将通过实践证明uni-app绝非是浪的虚名。</p>
<p>其实微信小程序开发也没必要纠结使用具体某一个框架,觉得哪个组件好用直接引入就好,也可谓是“集天下之大成”,总之适合自己的就好。</p>
<p>如果还在纠结微信小程序的框架选型不妨多看看多了解下,不然后面会浪费更多的时间成本和精力,可参考以下文章。</p>
<p>跨端框架深度评测:微信原生、wepy、mpvue、uni-app、taro、chameleon</p>
<h2 id="3-项目演示">3. 项目演示</h2>
<ul>
<li>项目概览</li>
</ul>
<p><img src="https://i.loli.net/2020/10/25/vKJShjEPHm2Dce8.png" alt="" loading="lazy"></p>
<ul>
<li>后台微服务</li>
</ul>
<p><img src="https://i.loli.net/2020/10/25/mjaXIngfeks6dOA.png" alt="" loading="lazy"></p>
<p><img src="https://i.loli.net/2020/10/25/jKzRahSeUG9gTrq.png" alt="" loading="lazy"></p>
<ul>
<li>管理前端</li>
</ul>
<p><img src="https://i.loli.net/2020/10/26/z3XiWdjcTORUM71.gif" alt="" loading="lazy"></p>
<ul>
<li>微信小程序端</li>
</ul>
<p><img src="https://i.loli.net/2020/10/25/Ns1Ep6wqyV9MrYx.gif" alt="" loading="lazy"></p>
<ul>
<li>移动APP端</li>
</ul>
<p><strong>APP介绍:</strong>vant实战 | 第一篇:有来商城移动端APP项目介绍</p>
<h1 id="三-项目实战">三. 项目实战</h1>
<h2 id="1-开发工具">1. 开发工具</h2>
<p>作为一位Java Developer来说,日常开发来说IDEA基本完全够用了,但是微信小程序开发必须要有<strong>微信开发者工具</strong>,除此之外因为使用的是uni-app框架,官方推荐使用的是<strong>HBuilderX</strong>,点击以下名称即可跳转官方地址下载。</p>
<p>微信开发者工具</p>
<p>HBuilderX</p>
<p><strong>PS:</strong> 习惯了IDEA的快捷键童靴们在使用HBuilderX开发之前,建议预先切换下快捷键方案,是不是很人性化的一个开发工具。</p>
<p><img src="https://i.loli.net/2020/10/26/ctngMyRaWdElIib.png" alt="" loading="lazy"></p>
<h2 id="2-个人微信小程序开发申请">2. 个人微信小程序开发申请</h2>
<p>进入微信公众平台申请小程序开发,创建小程序后在开发一栏的开发设置得到对应的AppID(小程序ID),下文需要。</p>
<p><img src="https://i.loli.net/2020/10/25/TwdrSfAu43nq1Ny.png" alt="" loading="lazy"></p>
<p><strong>PS:</strong> 有来商城项目是基于个人小程序开发,个人相较于企业少了很多接口权限,例如获取用户手机号、调用微信支付接口等。相信大多数童鞋没有条件得到企业号,也舍不得在没有必要的情况花几千块钱注册个公司。不过个人号基本够用了,也可以通过“曲线救国”的方式弥补个人号的不足,举个栗子,可以使用XorPay、Payjs等第三方支付平台弥补个人号无法调用支付接口的问题。</p>
<h2 id="3-创建uni-app商城模板">3. 创建uni-app商城模板</h2>
<p>后端开发人员一般来说不太擅长前端页面的设计开发,那该怎么快速开发微信商城小程序页面呢?</p>
<p>还记得上面说的很神奇的uni-app框架吗?它提供了插件市场,里面有很多基于uni-app开发的组件和模板。</p>
<p>uni-app插件市场</p>
<p><img src="https://i.loli.net/2020/10/25/pQ7NnIi8bAu3Wrk.png" alt="" loading="lazy"></p>
<p>搜索关键词“mall”,选择下载量最多的项目模板点击进入</p>
<p><img src="https://i.loli.net/2020/10/25/j5rCgVnXmOykMUA.png" alt="" loading="lazy"></p>
<p>点击“使用HBuilderX导入插件”,便可自动启动应用和加载项目至工作空间。</p>
<p><img src="https://i.loli.net/2020/10/25/Xdr6YA1MWLgJD5B.png" alt="" loading="lazy"></p>
<h2 id="4-配置微信小程序接入spring-cloud-oauth2认证中心">4. 配置微信小程序接入Spring Cloud OAuth2认证中心</h2>
<h3 id="41--微信小程序">4.1微信小程序</h3>
<p>导入的商城模板默认的是本地JSON数据,那么接入后台微服务需要封装axios请求,此外还需添加vuex来对状态进行管理,这两项引自vue-element-admin,细节请参考源码 youlai-mall-weapp,微信小程序调整步骤如下:</p>
<p>4.1.1 修改导入模板项目名称为youlai-mall-weapp,并在manifest.json配置AppID</p>
<p><img src="https://i.loli.net/2020/10/26/kp5UWH8XdMlt4EP.png" alt="" loading="lazy"></p>
<p>4.1.2 封装请求axios</p>
<p><img src="https://i.loli.net/2020/10/26/IPqknGbTmZF1iUd.png" alt="" loading="lazy"></p>
<p>4.1.3 添加状态管理vuex</p>
<p><img src="https://i.loli.net/2020/10/26/rBOQ175khESqaiL.png" alt="" loading="lazy"></p>
<p>4.1.4. 登录页面以及授权登录代码逻辑调整</p>
<p><img src="https://i.loli.net/2020/10/26/c1v9mlyXdkDbGrU.png" alt="" loading="lazy"></p>
<p>4.1.5. 微信小程序启动</p>
<p><img src="https://i.loli.net/2020/10/26/RxEIHut9fvbTcpZ.gif" alt="" loading="lazy"></p>
<p><img src="https://i.loli.net/2020/10/26/tdruKN9hjx42TUy.png" alt="" loading="lazy"></p>
<h3 id="42--后台微服务">4.2后台微服务</h3>
<p>4.2.1 微信授权登录接入认证中心</p>
<p><img src="https://i.loli.net/2020/10/26/6ljXE15AGnmOqbZ.png" alt="" loading="lazy"></p>
<pre><code class="language-java">private Result handleForWxAppAuth(Principal principal, Map&lt;String, String&gt; parameters) throws WxErrorException, HttpRequestMethodNotSupportedException {

      String code = parameters.get("code");
      if (StrUtil.isBlank(code)) {
            throw new BizException("code不能为空");
      }

      WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
      String openid = session.getOpenid();
      String sessionKey = session.getSessionKey();

      Result&lt;MemberDTO&gt; result = remoteUmsMemberService.loadMemberByOpenid(openid);
      if (!ResultCode.SUCCESS.getCode().equals(result.getCode())) {
            throw new BizException("获取会员信息失败");
      }
      MemberDTO memberDTO = result.getData();
      String username;
      if (memberDTO == null) { // 微信授权登录 会员信息不存在时 注册会员
            String encryptedData = parameters.get("encryptedData");
            String iv = parameters.get("iv");

            WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
            if (userInfo == null) {
                throw new BizException("获取用户信息失败");
            }
            UmsMember member = new UmsMember()
                  .setNickname(userInfo.getNickName())
                  .setAvatar(userInfo.getAvatarUrl())
                  .setGender(Integer.valueOf(userInfo.getGender()))
                  .setOpenid(openid)
                  .setUsername(openid)
                  .setPassword(passwordEncoder.encode(openid).replace(AuthConstants.BCRYPT, Strings.EMPTY)) // 加密密码移除前缀加密方式 {bcrypt}
                  .setStatus(Constants.STATUS_NORMAL_VALUE);

            Result res = remoteUmsMemberService.add(member);
            if (!ResultCode.SUCCESS.getCode().equals(res.getCode())) {
                throw new BizException("注册会员失败");
            }
            username = openid;
      } else {
            username = memberDTO.getUsername();
      }

      // oauth2认证参数对应授权登录时注册会员的username、password信息,模拟通过oauth2的密码模式认证
      parameters.put("username", username);
      parameters.put("password", username);

      OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
      Oauth2Token oauth2Token = Oauth2Token.builder()
                .token(oAuth2AccessToken.getValue())
                .refreshToken(oAuth2AccessToken.getRefreshToken().getValue())
                .expiresIn(oAuth2AccessToken.getExpiresIn())
                .build();
      return Result.success(oauth2Token);

    }
</code></pre>
<p><strong>声明:</strong> 这里的微信登录是基于微信授权快捷登录的方式而非表单,所以在第一次授权登录时注册的会员信息用户名和密码通过自定义方式生成,此后在OAuth2认证时携带这两个参数完成密码模式认证并生成token返回给微信小程序端。如果使用表单注册/登录,替换username和password即可。</p>
<h1 id="四-结语">四. 结语</h1>
<p>最后分享一些个人心得吧(倚老卖老),其实学好一门技术的我们心里都知道最有效的办法就是能够在实际场景运用它。自己虽然做了6年的开发,可惜现在还是在小公司做CRUD,不甘心又无奈,根本原因呢就是自己技术太菜。所以利用平时空闲时间创建了youlai-mall项目,并且为此买了三台云主机,虽然都是活动买的最便宜的那种,但至少对技术的态度是认证的。</p>
<p><img src="https://i.loli.net/2020/10/25/uHPiDBWA9Rdl4V3.png" alt="" loading="lazy"></p>
<p>初衷就是想把像分布式、高并发等技术引入整合到这个项目,通过实战来加深对技术的理解,就是挺无奈的没有环境那就自己创建环境吧。对项目有兴趣小伙伴欢迎联系我(微信号:haoxianrui)一起加入开发呗。最后觉得对你多多少少有帮助的话可以给个项目star呗,谢谢了~</p>
<table>
<thead>
<tr>
<th>项目名称</th>
<th>地址</th>
</tr>
</thead>
<tbody>
<tr>
<td>后台</td>
<td>youlai-mall</td>
</tr>
<tr>
<td>管理前端</td>
<td>youlai-mall-admin</td>
</tr>
<tr>
<td>微信小程序</td>
<td>youlai-mall-weapp</td>
</tr>
</tbody>
</table>
<p>期待你的加入和建议,有问题随时联系我~(微信号:haoxianrui)</p><br><br>
来源:https://www.cnblogs.com/haoxianrui/p/13882310.html
頁: [1]
查看完整版本: uni-app实战 | 第一篇:从0到1快速开发一个开源商城微信小程序,无缝接入Spring Security OAuth2认证授权实现登录