会复活的小强 發表於 2020-3-6 16:24:00

微信开放平台开发第三方授权登陆(四):微信小程序

<p>本文转载自:https://blog.csdn.net/qq_34190023/article/details/82351505</p>
<p>开发小程序需要在公众平台注册一个小程序账号,然后获取到小程序的AppID和AppSecret。就可以进行第三方登陆授权开发。</p>
<h1>一、需求</h1>
<p>拥有第三方微信登录功能,并获取到用户信息。</p>
<h1>二、开发流程</h1>
<p>小程序:</p>
<p>1. 微信小程序通过wx.login API进行登录获取code。由于AppID和AppSecret不能泄露给用户,根据code获取openid需要在服务端完成,所以需要将code发送给服务端</p>
<p>(服务端),并且带上授权临时票据code参数;</p>
<p>2. 服务端通过code和appid、APPSecret获取到openid和SessionKey。服务端需要返回自定义登录态给前端,不能返回SessionKey</p>
<p>3. 前端保存自定义登录态,获取用户信息时携带自定义登录态给后端。<br><img src="https://img2020.cnblogs.com/i-beta/1377406/202003/1377406-20200306161234873-1963165657.png" alt=""></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>获取Token的流程&nbsp;</p>
<h1 id="%E4%B8%89%E3%80%81%E5%BC%80%E5%8F%91%E4%BD%BF%E7%94%A8%E7%9A%84%E6%8A%80%E6%9C%AF%E5%8F%8A%E5%B7%A5%E5%85%B7">三、开发使用的技术及工具</h1>
<p>1、.后端采用IDEA2017 进行开发</p>
<p>2、前端使用微信开发者工具V1.02进行开发</p>
<p>3、使用fastJson对json数据进行处理</p>
<h1>四、具体实现步骤</h1>
<h2 id="1.%E5%89%8D%E7%AB%AF(%E5%B0%8F%E7%A8%8B%E5%BA%8F)">1.前端(小程序)</h2>
<p>目录结构如下:</p>
<p><img src="https://img2020.cnblogs.com/i-beta/1377406/202003/1377406-20200306161542796-1431353491.png" alt=""></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3 id="1%EF%BC%89%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9A%84%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F">1)自定义的全局变量</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">globalData: {

    userInfo: </span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">,

    sessionkey:</span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">

}</span></pre>
</div>
<p>自定义userInfo用于存储用户信息</p>
<p>sessionKey用于存储服务端发回给客户端的sessionkey</p>
<h3>2)index加载时进行登录</h3>
<p>用户登录后,服务端会返回一个sessionkey给客户端保存,如果为空,说明没有登录过,需要调用wx.login进行登录。</p>
<p>调用wx.login后,微信会返回一个code给小程序,小程序需要通过这个code发送给自身的服务端来获取sessionkey和openid信息。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">onLoad: function() {

&nbsp;&nbsp;&nbsp; var serverUrl </span>=<span style="color: rgba(0, 0, 0, 1)"> app.serverUrl;

&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 加载时,检查当前用户信息是否登录</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">if</span> (app.globalData.sessionkey != <span style="color: rgba(0, 0, 255, 1)">null</span>) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 已经登录了

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 是否授权</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wx.getSetting({

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; success: function(res) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">if</span> (res.authSetting['scope.userInfo'<span style="color: rgba(0, 0, 0, 1)">]) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 已经授权,可以直接调用 getUserInfo 获取头像昵称</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wx.getUserInfo({

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; success: function(res) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; app.globalData.userInfo </span>=<span style="color: rgba(0, 0, 0, 1)"> JSON.parse(res.rawData);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; })

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {

&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 还没有授权,则需要授权</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wx.redirectTo({

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url: </span>'../authorization/authorization'<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; })

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; })

&nbsp;&nbsp;&nbsp; } </span><span style="color: rgba(0, 0, 255, 1)">else</span> { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 还没有登录

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 提示用户登录授权</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wx.login({

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; success: res </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 发送 res.code 到后台换取 openId, sessionKey, unionId</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (res.code) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 发送请求,服务端能获取到openid和unionid,之前登录过则可以获取到之前的用户信息。</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wx.request({

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url: serverUrl </span>+ '/miniprogram/login/' + res.code, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">请求路径</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; method: </span>"GET"<span style="color: rgba(0, 0, 0, 1)">,

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; success: function(res) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; app.globalData.sessionkey </span>=<span style="color: rgba(0, 0, 0, 1)"> res.data;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 进入授权</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wx.redirectTo({

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url: </span>'../authorization/authorization'<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; })

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; })

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; })

&nbsp;&nbsp;&nbsp; }

},</span></pre>
</div>
<p>登录成功后,重定向到授权页面</p>
<h3 id="3%EF%BC%89%E6%8E%88%E6%9D%83%E9%A1%B5%E9%9D%A2authorization.wxml">3)授权页面authorization.wxml</h3>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre>&lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>='tag-title'&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp; </span>&lt;image mode="widthFix" style=' width: 200rpx;height: 200rpx;margin-top:150rpx' src="/images/logo.jpg"&gt;&lt;/image&gt;

&lt;/view&gt;

&lt;view wx:<span style="color: rgba(0, 0, 255, 1)">if</span>="{{canIUse}}"&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp; </span>&lt;view style='text-align:center;margin-top:50rpx'&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp; 允许微信授权后,可体验更多功能</span>&lt;/view&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp; </span>&lt;view&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp; </span>&lt;button open-type='getUserInfo' bindgetuserinfo="bindGetUserInfo" &gt;授权登录&lt;/button&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp; </span>&lt;button bindtap='navigateBack'&gt;返回首页&lt;/button&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp; </span>&lt;/view&gt;

&lt;/view&gt;

&lt;view wx:<span style="color: rgba(0, 0, 255, 1)">else</span> style='text-align:center;margin-top:50rpx'&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp; 您的微信版本过低,请升级后再次体验</span>&lt;/view&gt;</pre>
</div>
<p>Button的open-type为getUserInfo时,点击后会调用bindgetuserinfo属性配置的函数,同时带上用户基本信息(不包括Openid等)</p>
<h3 id="4%EF%BC%89%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF%E5%8F%91%E9%80%81%E7%BB%99%E5%90%8E%E7%AB%AF">4)用户信息发送给后端</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 授权登录按钮</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp; bindGetUserInfo: function(e) {

&nbsp;&nbsp;&nbsp; let that </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">;

&nbsp;&nbsp;&nbsp; var serverUrl </span>=<span style="color: rgba(0, 0, 0, 1)"> app.serverUrl;

&nbsp;&nbsp;&nbsp; console.log(e.detail.userInfo)

&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">if</span> (e.detail.userInfo) {&nbsp; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 成功获取到信息</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; app.globalData.userInfo </span>=<span style="color: rgba(0, 0, 0, 1)"> e.detail.userInfo

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 这里可以将用户信息发送给后台

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取到sessionkey</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">if</span> (app.globalData.sessionkey!=<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">){

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wx.request({

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url: serverUrl </span>+ '/miniprogram/userinfo', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">请求路径,</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; method: </span>"GET"<span style="color: rgba(0, 0, 0, 1)">,

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data: {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> openid: this.openid,

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> unionid: this.unionid,</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key: app.globalData.sessionkey,

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nickname: app.globalData.userInfo.nickName, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取昵称</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gender: app.globalData.userInfo.gender, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取性别</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; province: app.globalData.userInfo.province, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取省份</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; city: app.globalData.userInfo.city, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取城市</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; country: app.globalData.userInfo.country, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取国家</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; avatarUrl: app.globalData.userInfo.avatarUrl, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这些是用户的基本信息</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; language: app.globalData.userInfo.language

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; success: function (res) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">if</span> (res.data.code == 0) {&nbsp; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 请求成功</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debugger

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; app.globalData.userInfo </span>= res.data.data; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 以数据库中返回的数据为准

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取用户信息成功</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wx.switchTab({

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url: </span>'../mine/mine'<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; })

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; })

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">this</span>.showZanTopTips('错误:SessionKey为null'<span style="color: rgba(0, 0, 0, 1)">);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }



&nbsp;&nbsp;&nbsp; } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">this</span>.showZanTopTips('您拒绝了微信授权'<span style="color: rgba(0, 0, 0, 1)">);

&nbsp;&nbsp;&nbsp; }

&nbsp; },



}));</span></pre>
</div>
<p>获取用户信息成功后,页面跳转到mine中显示用户详情信息</p>
<h3 id="5%EF%BC%89%E7%94%A8%E6%88%B7%E8%AF%A6%E6%83%85%E9%A1%B5mine.wxml">5)用户详情页mine.wxml</h3>
<div class="cnblogs_code">
<pre>&lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>="container more"&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp; </span>&lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>="userinfo"&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp; </span>&lt;image bindtap="bindViewTap" <span style="color: rgba(0, 0, 255, 1)">class</span>="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"&gt;&lt;/image&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp; </span>&lt;text <span style="color: rgba(0, 0, 255, 1)">class</span>="userinfo-nickname"&gt;{{userInfo.nickName}}&lt;/text&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;text <span style="color: rgba(0, 0, 255, 1)">class</span>="userinfo-nickname"&gt;性别:{{userInfo.gender === 1 ? '男':'女'}}&lt;/text&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&lt;text <span style="color: rgba(0, 0, 255, 1)">class</span>="userinfo-nickname"&gt;城市:{{userInfo.city}}&lt;/text&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;text <span style="color: rgba(0, 0, 255, 1)">class</span>="userinfo-nickname"&gt;省份:{{userInfo.province}}&lt;/text&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;text <span style="color: rgba(0, 0, 255, 1)">class</span>="userinfo-nickname"&gt;国家:{{userInfo.country}}&lt;/text&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;text <span style="color: rgba(0, 0, 255, 1)">class</span>="userinfo-nickname"&gt;使用语言:{{userInfo.language}}&lt;/text&gt;<span style="color: rgba(0, 0, 0, 1)">

&nbsp; </span>&lt;/view&gt;

&lt;/view&gt;</pre>
</div>
<h2>2.服务端(Java)</h2>
<p>服务端需要做的是:接受小程序前端发送的请求,根据发送过来的code,以及服务端保存的AppId和APPSecret等向微信服务端发送请求,获取到sessionkey和openid,然后将二者关联起来保存到session存储器中(Redis),返回给前端key值。</p>
<p>接受小程序发送过来的key和用户基本信息,根据key从redis中获取openid,然后对数据库进行查询,若存在数据则封装后返回给前端,若无信息则向数据库中插入数据并返回给前端。</p>
<h3>1).配置文件新增小程序相关配置</h3>
<div class="cnblogs_code">
<pre>wechat.miniprogram.appid =<span style="color: rgba(0, 0, 0, 1)">

wechat.miniprogram.appsecret </span>=</pre>
</div>
<h3>2)获取openid以及Sessionkey</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">@ResponseBody

&nbsp;&nbsp;&nbsp; @RequestMapping(</span>"/login/{code}"<span style="color: rgba(0, 0, 0, 1)">)

&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">public</span> String login(@PathVariable("code"<span style="color: rgba(0, 0, 0, 1)">) String code) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String url </span>= "https://api.weixin.qq.com/sns/jscode2session?" +<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>"appid=" +<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; env.getProperty(</span>"wechat.miniprogram.appid") +<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>"&amp;secret=" +<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;env.getProperty(</span>"wechat.miniprogram.appsecret") +<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>"&amp;js_code=" +<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; code </span>+<span style="color: rgba(0, 0, 0, 1)">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>"&amp;grant_type=authorization_code"<span style="color: rgba(0, 0, 0, 1)">;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSONObject object </span>=<span style="color: rgba(0, 0, 0, 1)"> HttpClientUtils.httpGet(url);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 请求,获取openid或unionid

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 从数据库中查询是否存储

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 成功获取</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String unionid </span>= (String) object.get("unionid"<span style="color: rgba(0, 0, 0, 1)">);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String openid </span>= (String) object.get("openid");<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">用户唯一标识

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 会话密钥session_key 是对用户数据进行加密签名的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;String session_key </span>= (String) object.get("session_key"<span style="color: rgba(0, 0, 0, 1)">);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String key </span>= "wechatminiprogramkey-" + UUID.randomUUID().toString().replaceAll("-", ""<span style="color: rgba(0, 0, 0, 1)">);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RedisPoolUtil.setEx(key, openid </span>+ "---" + session_key, 9600<span style="color: rgba(0, 0, 0, 1)">);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> key;

}</span></pre>
</div>
<h3 id="3).%E8%8E%B7%E5%8F%96%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF%EF%BC%9A">3).获取用户信息:</h3>
<p>小程序能够获取用户基本信息,但是不包括openid等信息,仅有基本的昵称等信息,需要通过后端传输的key作为标识发送到前端,然后找到对应的openid来获取。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">@ResponseBody

@RequestMapping(value </span>= "/userinfo", method = RequestMethod.GET) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取用户信息</span>

<span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Result getOpenId(String key, MiniProgramBaseUserInfo miniProgramBaseUserInfo) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MiniProgramBaseUserInfo result </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String value </span>=<span style="color: rgba(0, 0, 0, 1)"> RedisPoolUtil.get(key);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">if</span> (value != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String values[] </span>= value.split("---"<span style="color: rgba(0, 0, 0, 1)">);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String openid </span>= values;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 从数据库中查询是否存储(根据openid查询)</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result </span>= <span style="color: rgba(0, 0, 255, 1)">null</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO: 这里是查数据库操作</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">if</span> (result == <span style="color: rgba(0, 0, 255, 1)">null</span>){ <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 数据库中没有数据

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO: 向数据库中执行插入操作

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> insert&nbsp; weChatUserInfo</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result </span>=<span style="color: rgba(0, 0, 0, 1)"> miniProgramBaseUserInfo;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Result.success(result);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: rgba(0, 0, 255, 1)">return</span> Result.error(SESSION_KEY_OVER_TIME); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> SessionKey失效</span>
<span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;&nbsp; }</span></pre>
</div>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
   
<div class="div_masklayer" id="div_masklayer"></div>
<div class="div_popup" id="Div_popup"> <img class="img_zfb" id="img_zfb" src="https://www.cnblogs.com/images/cnblogs_com/alimayun/1442965/o_%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20190413152742.jpg">
</div>


<div class="autograph">
<div class="blogds">如果想给予我更多的鼓励,<span class="bold">求打</span></div>
<p>因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【<strong>阿里马云</strong>】!</p>
</div><br><br>
来源:https://www.cnblogs.com/alimayun/p/12427261.html
頁: [1]
查看完整版本: 微信开放平台开发第三方授权登陆(四):微信小程序