使用uView UI+UniApp开发微信小程序--微信授权绑定和一键登录系统
<p>在前面随笔《使用uView UI+UniApp开发微信小程序》和《使用uView UI+UniApp开发微信小程序--判断用户是否登录并跳转》介绍了微信小程序的常规登录处理和验证码登录处理的一些经验,本篇随笔继续介绍第三种登录方式,微信授权登录。微信授权登录是系统用户表绑定了微信小程序OpenID后,通过前端发起微信的登录授权,顺利获得微信授权后获得code,并在我们自己的服务后台接口通过code解析出用户的OpenId,然后获得对应用户的身份token信息返回给前端,前端完成登录后的跳转处理。</p><h3> 1、微信授权登录界面</h3>
<p>我们前面介绍过常规的账号密码登录处理和验证码登录处理,第三种登录方式微信授权登录也是很常见的,因此整合在系统中方便使用,界面效果如下所示。</p>
<p><img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926101349772-646195874.png" alt="" width="242" height="348" loading="lazy"></p>
<p>这个界面很简单,只需要提供一个按钮触发授权登录即可。</p>
<p>不过,授权登录需要用户登录系统后绑定微信才能进行一键登录,否则是无法识别用户的openid,也就无法一键登录了。</p>
<p><img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926102513448-1399277887.png" alt="" width="245" height="355" loading="lazy"></p>
<p> 一旦绑定微信,也就是建立了用户和小程序OpenId 之间的关联,也就可以实现微信授权登录了。授权绑定需要获取用户信息,因此需要发起用户授权的确认操作,如下界面所示。</p>
<p><img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926102805918-475205471.png" alt="" loading="lazy"></p>
<p> 如果需要取消,那么随时取消授权也可以,系统提供入口处理即可,一般在同一界面中根据状态绑定或者解绑。</p>
<p><img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926102833699-1190046614.png" alt="" width="243" height="345" loading="lazy"></p>
<p> 以上就是大概的界面处理流程,剩下的就是我们需要编码实现相应的逻辑即可。</p>
<p> </p>
<h3>2、微信授权绑定和一键登录系统处理</h3>
<p>用户授权绑定或者解绑,我们通过状态来识别提供相关的功能即可,如下界面代码所示。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">view </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="bottom"</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">u-button </span><span style="color: rgba(255, 0, 0, 1)">v-if</span><span style="color: rgba(0, 0, 255, 1)">="<span style="font-size: 15px"><strong>!vuex_user.openid</strong></span>"</span><span style="color: rgba(255, 0, 0, 1)"> shape</span><span style="color: rgba(0, 0, 255, 1)">="circle"</span><span style="color: rgba(255, 0, 0, 1)"> type</span><span style="color: rgba(0, 0, 255, 1)">="success"</span><span style="color: rgba(255, 0, 0, 1)"> @click</span><span style="color: rgba(0, 0, 255, 1)">="authLogin"</span><span style="color: rgba(0, 0, 255, 1)">></span>授权绑定<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">u-button</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">u-button </span><span style="color: rgba(255, 0, 0, 1)">v-else shape</span><span style="color: rgba(0, 0, 255, 1)">="circle"</span><span style="color: rgba(255, 0, 0, 1)"> type</span><span style="color: rgba(0, 0, 255, 1)">="error"</span><span style="color: rgba(255, 0, 0, 1)"> @click</span><span style="color: rgba(0, 0, 255, 1)">="cancelBind"</span><span style="color: rgba(0, 0, 255, 1)">></span>取消绑定<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">u-button</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">u-gap </span><span style="color: rgba(255, 0, 0, 1)">height</span><span style="color: rgba(0, 0, 255, 1)">="20"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">u-gap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">u-button </span><span style="color: rgba(255, 0, 0, 1)">shape</span><span style="color: rgba(0, 0, 255, 1)">="circle"</span><span style="color: rgba(255, 0, 0, 1)"> @click</span><span style="color: rgba(0, 0, 255, 1)">="gotoMyInfo"</span><span style="color: rgba(0, 0, 255, 1)">></span>返回我的页面<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">u-button</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">view</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
</div>
<p>微信授权登录的绑定微信操作代码如下所示。</p>
<p><img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926103306093-1901546805.png" alt="" loading="lazy"></p>
<p> 首先先通过uni.getUserProfile获得用户信息,返回的信息,不包括openid信息,只是一些基础的昵称,头像等信息,如下所示</p>
<p><img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926103541504-2141286185.png" alt="" loading="lazy"></p>
<p> </p>
<p>不过它本身的加密信息,是我们可以通过它来在服务器后端解析出来openid的。注意,前端在正式发布后,腾信API是不在授权名单中,因此不能通过纯前端的方式解析openid,除非通过定义云函数方式调用(也就是离不开服务器)。</p>
<p>我们这里通过服务器端进行解析,因此服务端的域名是在授权Https列表中的</p>
<p><img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926103943519-1895986621.png" alt="" loading="lazy"></p>
<p>一般服务器端的接口顺利获取openid等数据,就直接resolve执行成功的回调操作</p>
<p>服务端直接通过jscode2session的处理即可获取对应的数据了</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">public</span> JSCode2SessionResult JSCode2Session(<span style="color: rgba(0, 0, 255, 1)">string</span> appid, <span style="color: rgba(0, 0, 255, 1)">string</span> secret, <span style="color: rgba(0, 0, 255, 1)">string</span> js_code, <span style="color: rgba(0, 0, 255, 1)">string</span> grant_type = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">authorization_code</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = <span style="color: rgba(0, 0, 255, 1)">string</span>.Format(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type={3}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, appid, secret, js_code, grant_type);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result = WeJsonHelper<JSCode2SessionResult><span style="color: rgba(0, 0, 0, 1)">.ConvertJson(url);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result;
}</span></pre>
</div>
<p>如果前端通过下面代码测试非正式的环境,也可以获得openid,正式环境下,小程序不接受https://api.weixin.qq.com的域名的。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"> uni.request({
url: </span>'https://api.weixin.qq.com/sns/jscode2session?appid=' +<span style="color: rgba(0, 0, 0, 1)">
data.appid </span>+
'&secret=' +<span style="color: rgba(0, 0, 0, 1)">
data.secret </span>+
'&js_code=' +<span style="color: rgba(0, 0, 0, 1)">
loginRes.code </span>+
'&grant_type=authorization_code'<span style="color: rgba(0, 0, 0, 1)">,
success: codeRes </span>=><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(codeRes)</span>
<span style="color: rgba(0, 0, 0, 1)"> resolve(codeRes.data)
},
fail: () </span>=><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> tips = '获取 SesssionKey OpenId 失败'<span style="color: rgba(0, 0, 0, 1)">
vm.$u.toast(tips)
reject(tips)
},
})</span></pre>
</div>
<p>一般我们获得用户的openid等详细信息,我们可以把这些信息写入服务器的相关表中,并更新用户的openid即可</p>
<p><img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926104630853-2027890221.png" alt="" loading="lazy"></p>
<p>服务端接口接受用户数据,并写入或者更新小程序用户表信息,同时更新系统用户的openid即可。</p>
<p><img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926104852092-173772190.png" alt="" loading="lazy"></p>
<p>一般前端顺利获得结果,就跳转用户页面即可。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;"> setTimeout(() => {
uni.switchTab({ url: '/pages/task/login/myinfo' });
}, 3000);</pre>
</div>
<p> 而取消用户绑定,只需要置空服务器端用户表对应记录的openId,并置空本地用户的openid信息即可。</p>
<div class="cnblogs_code">
<pre>cancelBind() { <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)">var</span> param = {id: <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.vuex_user.id}
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.$u.api.User.<span style="font-size: 15px"><strong>CancelBindWechat</strong></span>(param).then(res=><span style="color: rgba(0, 0, 0, 1)"> {
console.log(res)
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(res.success){
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.$u.toast('已取消绑定'<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.$u.vuex(<span style="font-size: 15px"><strong>'vuex_user.openid', ''</strong></span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.$u.vuex('vuex_user.wechatInfo', <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)"> 重置微信信息</span>
<span style="color: rgba(0, 0, 255, 1)">this</span>.headimg = '/static/images/wx_ico.png'<span style="color: rgba(0, 0, 0, 1)">
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.$u.toast('取消绑定失败'<span style="color: rgba(0, 0, 0, 1)">)
}
})
},</span></pre>
</div>
<p>至此,我们就完成了用户绑定和解绑微信的相关操作了。剩下的就是我们需要处理登录界面上一键登录的处理了。</p>
<p><img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926101349772-646195874.png" alt="" width="242" height="348" loading="lazy"></p>
<p>登录的方法代码如下所示。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">login() {
let _self </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 0. 显示加载的效果</span>
uni.showLoading({ title: '登录中...'<span style="color: rgba(0, 0, 0, 1)"> });
</span><span style="color: rgba(0, 0, 255, 1)">var</span> data =<span style="color: rgba(0, 0, 0, 1)"> {}
_self.$u.api.User.<span style="font-size: 15px"><strong>wechatlogin</strong></span>(data) </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">微信登陆授权</span>
.then(res =><span style="color: rgba(0, 0, 0, 1)"> {
console.log(res);
uni.hideLoading();
_self.$u.toast(</span>'登录成功'<span style="color: rgba(0, 0, 0, 1)">);
<strong><span style="font-size: 15px"> uni.switchTab({
url: </span></strong></span><strong><span style="font-size: 15px">'/pages/task/login/myinfo'</span></strong><span style="color: rgba(0, 0, 0, 1)"><strong><span style="font-size: 15px">
});</span></strong>
})
.</span><span style="color: rgba(0, 0, 255, 1)">catch</span>(error =><span style="color: rgba(0, 0, 0, 1)"> {
console.log(error);
_self.error </span>=<span style="color: rgba(0, 0, 0, 1)"> error;
});
}</span></pre>
</div>
<p>也就是我们封装了一个微信授权登录的逻辑,一旦成功返回,就跳转到指定页面上去即可。</p>
<p>其中封装的Promise函数逻辑代码如下所示</p>
<p> <img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926105802020-2088256740.png" alt="" loading="lazy"></p>
<p> 先在前端发起登录处理,获得code提交给服务器进行处理验证即可。</p>
<p>大概的步骤分为:</p>
<p>1)通过code 换取 session_key</p>
<p>2)从系统中判断是否存在用户</p>
<p>3)根据用户身份生成tokenresult</p>
<p>代码逻辑如下所示</p>
<p><img src="https://img2020.cnblogs.com/blog/8867/202109/8867-20210926110305015-954870974.png" alt="" loading="lazy"></p>
<p> </p>
<p> 以上就是微信授权绑定和一键登录系统的相关处理逻辑及代码,其实无论常规的账号密码登陆、短信验证码登陆、微信一键登录,大致的处理过程都大同小异,就是先通过直接或者间接的方式确认用户身份的有效性,然后获得用户的信息,构建返回的token令牌信息给前端使用即可。前端则负责处理结果逻辑,是提示用户还是顺利跳转到默认用户页面即可。</p>
<p>相关文章:</p>
<p>使用uView UI+UniApp开发微信小程序</p>
<p>使用uView UI+UniApp开发微信小程序--判断用户是否登录并跳转</p>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
<div style="border-right-color: #cccccc; border-right-width: 1px; border-right-style: solid; padding-right: 5px; border-top-color: #cccccc; border-top-width: 1px; border-top-style: solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left-color: #cccccc; border-left-width: 1px; border-left-style: solid; width: 98%; padding-top: 4px; border-bottom-color: #cccccc; border-bottom-width: 1px; border-bottom-style: solid; background-color: #eeeeee;">
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" alt>
<span style="color: #000000"><span class="Apple-tab-span" style="white-space: pre"></span>
专注于代码生成工具、.Net/Python 框架架构及软件开发,以及各种Vue.js的前端技术应用。著有Winform开发框架/混合式开发框架、微信开发框架、Bootstrap开发框架、ABP开发框架、SqlSugar开发框架、Python开发框架等框架产品。
<br> 转载请注明出处:撰写人:伍华聪 http://www.iqidi.com <br> </span></div><br><br>
来源:https://www.cnblogs.com/wuhuacong/p/15336811.html
頁:
[1]