空语者 發表於 2020-3-6 22:40:00

微信小程序开发技巧总结(三)-- 云开发时效数据刷新和存储 (access_token等)

<h3 id="小程序云开发时效数据刷新和存储-access_token等">小程序云开发时效数据刷新和存储 (access_token等)</h3>
<h4 id="1问题描述">1.问题描述</h4>
<p>小程序中经常有需要进行OCR识别,或者使用外部api例如百度AI识别等接口,请求调用这些接口需要令牌,即一些具有时效性的数据。本文以小程序云开发使用百度API接口为例,介绍access_token定时刷新和请求机制。</p>
<p>下面是百度调用身份证识别的一段需求,需要传的参数需要有access_token。</p>
<p><strong>请求示例</strong></p>
<p>HTTP 方法:<code>POST</code></p>
<p>请求URL: <code>https://aip.baidubce.com/rest/2.0/ocr/v1/idcard</code></p>
<p>URL参数:</p>
<table>
<thead>
<tr>
<th>参数</th>
<th>值</th>
</tr>
</thead>
<tbody>
<tr>
<td>access_token</td>
<td>通过API Key和Secret Key获取的access_token,参考“Access Token获取”</td>
</tr>
</tbody>
</table>
<p>access_token 是具有时效性的数据,每次请求一次接口就进行一次请求刷新,显然是对计算机资源的极大浪费,且影响效率。</p>
<h4 id="2问题解决方案">2.问题解决方案</h4>
<p><img src="https://gitee.com/Kindear/BlogAssets/raw/master/cnblogs/%E6%95%99%E5%8A%A1%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1%E7%94%A8%E4%BE%8B%E5%9B%BE.jpg" alt="" loading="lazy"></p>
<p><strong>2.1.云数据库配置</strong></p>
<p>新建一个云数据库名为<strong>setconfig</strong>。作为配置型信息存储数据库,类似access_token的数据都可以向其中存储。</p>
<p>对access_token配置下列字段:</p>
<ol>
<li>_openid (你的openid* 必填)</li>
<li>config_name (配置名,填access_token)</li>
<li>value (access_token的值,默认为null)</li>
</ol>
<p>id会自动生成,配置完效果如下(这个value是已经更新后的值)</p>
<p><img src="https://gitee.com/Kindear/BlogAssets/raw/master/cnblogs/20200306221725.png" alt="" loading="lazy"></p>
<p><strong>2.2 定时云函数配置</strong></p>
<p>阅读access_token获取的文档,可知,我们需要请求一个地址来获取access_token的值。</p>
<h5 id="获取access_token">获取Access_Token</h5>
<p><strong>请求URL数据格式</strong></p>
<p>向授权服务地址<code>https://aip.baidubce.com/oauth/2.0/token</code>发送请求(推荐使用POST),并在URL中带上以下参数:</p>
<ul>
<li><strong>grant_type:</strong> 必须参数,固定为<code>client_credentials</code>;</li>
<li><strong>client_id:</strong> 必须参数,应用的<code>API Key</code>;</li>
<li><strong>client_secret:</strong> 必须参数,应用的<code>Secret Key</code>;</li>
</ul>
<p>例如:</p>
<p><code>https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&amp;client_id=Va5yQRHlA4Fq5eR3LT0vuXV4&amp;client_secret=0rDSjzQ20XUj5itV6WRtznPQSzr5pVw2&amp;</code></p>
<p><strong>实现</strong></p>
<p>我们需要在云函数中模拟请求,并根据返回结果刷新云数据库中的access_token值。</p>
<p>想要运行通过该程序,需要开发者自己去百度创建账号并创建应用。</p>
<p><strong>云函数index.js</strong></p>
<pre><code class="language-js">// 云函数入口文件 index.js
const cloud = require('wx-server-sdk')

cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database()
var request = require('request')
// 定时器
exports.main = async(event, context) =&gt; {
const appkey = '填写你的百度AppKey';
const appsecret = '填写你的百度AppSecret';
var url = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&amp;client_id=' + appkey + '&amp;client_secret=' + appsecret;
return new Promise((resolve, reject) =&gt; {
    request({
      url: url,
      method: "POST",
      json: true,
      headers: {
      "content-type": "application/json",
      },
    }, function(error, response, body) {

      if (!error &amp;&amp; response.statusCode == 200) {
      console.log('通行证为' + body.access_token)
      resolve(body.access_token)
          //记得修改.doc('xxx') 中的内容
      db.collection('setconfig').doc('aaaf5a56-1dd9-4e50-974b-34688fa47b20').update({
          data: {
            value: body.access_token
          }

      }).then(res =&gt; {
          console.log('调用完成')
          console.log(res)
      })
      }
    })
})
}
</code></pre>
<p><strong>docid是setconfig生成的,每个人不同注意修改</strong></p>
<p>还有一种更新写法,不过更推荐使用上面的方法,效率更高,且稳定。</p>
<pre><code class="language-js">db.collection('setconfig').where({
        config_name:'access_token'
}).update({
data: {
      value: body.access_token
    }
})
</code></pre>
<p><strong>云函数config.json(定时触发器功能实现)</strong></p>
<pre><code class="language-json">{
"triggers": [
    {
      "name": "myTrigger",
      "type": "timer",
      "config": "0 0 2 * * * *"
    }
]
}
</code></pre>
<p>云函数整体结构为:</p>
<p><img src="https://gitee.com/Kindear/BlogAssets/raw/master/cnblogs/20200306223027.png" alt="" loading="lazy"></p>
<p>然后上传并部署(云端安装依赖)。</p>
<p><strong>2.3 小程序端获取Access_token</strong></p>
<p>在小程序进入相应界面的时候,请求云数据库,获取access_token</p>
<pre><code class="language-js">onLoad: function (options) {
    //页面初始化
    var that = this;
    db.collection('setconfig').where({
      config_name:'access_token'
    }).get({
      success(res){
      that.setData({
          access_token:res.data.value
      })
      //console.log(res.data)
      },
      fail(res){
      wx.showToast({
          title: '请求失败,无法通过扫描填充数据',
      })
      }
    })
},
</code></pre>
<h4 id="3-参考资料">3. 参考资料</h4>
<p>百度AI鉴权认证机制</p>
<p>微信小程序云开发数据库update函数更新不了数据的问题</p>
<p>小程序云开发定时触发器</p>
<p><em>小程序开发相关问题欢迎联系QQ 1025584691</em></p><br><br>
来源:https://www.cnblogs.com/masterchd/p/12431426.html
頁: [1]
查看完整版本: 微信小程序开发技巧总结(三)-- 云开发时效数据刷新和存储 (access_token等)