为了方便用户使用小程序时, 使用微信账号授权快速登录软件, 微信小程序提供了相关的授权接口. 小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识, 快速建立小程序内的用户体系. 以便但是对于新手来说, 配置起来还是有些难度.
本文将对小程序使用微信授权做较为详细的介绍, 并提供简单的服务端及客户端 demo 代码以方便大家学习. 在开始之前, 我们首先要了解几个知识点, 我们的目的是什么? 我们需要哪些参数? 用参数来做什么?
目标
我们的目标很简单, 能够让用户点击登录按钮后, 通过某种方式获取用户的相关信息, 而这里的信息是唯一的, 后续不管用户更换多少设备, 都能确定用户的唯一性. 而且这里的数据要足够安全, 不能任何人都能通过某种技术去获取. 这里的数据能够存储, 将这个数据存储在业务相关的服务器, 下次能够直接读取确认用户.
带着这几个目标, 我们发现微信其实提供了相关的登录能力, 系统了相关的 API 以方便我们使用, 比如小程序端的 wx.login, 服务器端的 code2Session, 微信接口端的 openid 等数据, 那么这这些参数, 这些数据有什么用呢? 请向下看.
流程
在开始之前, 我们先看看小程序官方给出的小程序登录流程时序图, 一下子没看懂? 没关系, 接下来就给大家做详细的介绍.
img
上面这张图与我们常见的流程图还是有些出入, 我通过自己的理解, 画出了下面的这张图, 我们一起来看看.
这张图是是简单了不少, 我们看到, 小程序首先通过 wx.login() 函数获取当前用户的 code, 然后再通过 wx.request 将 code 传送到服务器. 服务器端将 appid,appsecret,code 等参数通过 request 提交到微信服务接口, 微信服务接口反馈 openid,session_key 参数. 我们发现, 小程序通信不只是和服务器端进行了通信, 还与微信服务接口进行了通信, 那么, 这里的服务器端和微信服务端起着什么样的作用了, 在本流程中起着什么样子的角色呢?
小程序
小程序端, 我们需要两个函数及一个变量, 两个函数为 wx.login() 函数和 wx.request() 函数, 变量为 code 变量. 这两个函数及变量都是小程序官方提供的, 我们只需要直接使用即可.
wx.login() - wx.login() 在本教程中的目的是调用接口获取登录凭证 (code).
code - 用户登录凭证 (有效期五分钟), 登录凭证 code 只能使用一次.
wx.request() - wx.request() 将用户登录凭证 code 传输到开发者服务器后台调用.
在小程序的流程中, 其实主要就做了两件事, 第一件事是通过 wx.login() 函数生成 code, 第二件事就是通过 wx.request() 函数将 code 提交到你自己搭建的小程序的服务器.
wx.login() 这个 API 的作用就是为当前用户生成一个临时的登录凭证, 这个临时登录凭证的有效期只有五分钟. 有了这个凭证, 我们才能通过服务器获取当前用户的 appid.
wx.request() 这个 API 的作用发起 HTTPS 网络请求. 发起 HTTPS 请求的方式很多, 比如 GET,POST 等方式, 因篇幅限制, 本文就不过多介绍, 感兴趣的同学可以参考小程序 wx.request 官方文档. 本文仅使用 GET 方式进行传参.
服务器
在服务器端, 我们需要获取小程序的 appId, 小程序的 appSecret, 以及通过小程序 wx.request() 传输过来的 code, 还包括默认的授权类型, 我们填写 authorization_code 即可. 最后, 我们要通过官方的 authorization_code 方法, 获取 openid,session_key,unionid 等参数.
appId - 小程序的 ID, 这个 ID 是唯一的, 可以进入小程序设置 - 开发设置中获取.
appSecret - 小程序密钥, 也是唯一的, 可以进入小程序设置 - 开发设置中获取, 如果忘记, 可以点击重置.
1541140868225
微信服务接口
最后, 我们在服务器端将上面获取到的 appid,appSecret,code 参数 HTTP 请求微信服务器, 等待微信返回 openid,session_key,unionid 这三个参数. 之后, 在通过服务器鉴权, 给小程序返回相应数据.
openid - 用户唯一标识, 每个用户请求得到的标识不同, 但是同一用户每次请求得到的这个数据是相同的.
session_key - 会话密钥, 每次请求返回的会话密钥不同, 主要用于请求其他数据时解密. 会话密钥 session_key 是对用户数据进行 加密签名 的密钥. 为了应用自身的数据安全, 开发者服务器不应该把会话密钥下发到小程序, 也不应该对外提供这个密钥.
整体的流程就是这个样子, 可能有人问, 为什么我不直接在小程序端向微信服务器发起 HTTP 请求呢? 这样不需要微信接口服务, 直接从小程序端就能获取 openid 等数据了, 何必多此一举呢? 目的很简单, 为了数据安全, 将需要保密的数据都存放在服务器端, 防止数据暴漏, 这也是微信官方的建议, 将重要数据存储在服务器端, 微信会对这些数据做签名和加密处理. 开发者后台拿到开放数据后可以对数据进行校验签名和解密, 来保证数据不被篡改.
小程序端
明白了整体的流程和架构, 我们就可以开始撰写代码了, 首先, 我们需要安装开发环境, 及搭建好基础的代码框架, 没有经验的同学可以参考如何入门小程序开发这篇文章, 在此文中, 我们详细介绍了入门小程序应该具备的工具及代码. 我们需要在 index.JS 和 index.wxml 中插入下面的代码.
编辑 index.wxml, 插入下面的代码, 这里我们插入一个 button 来调用 wx_login() 函数, 每次点击请求登录按钮, 将会自动调用 index.JS 内的 wx_login() 函数. 之后, wx_login() 返回 openid 显示.(理论上来说 openid 不应该在客户端展示, 为了演示, 将 openid 发送至客户端, 如果在生产环境使用, 请尽量将 openid 保留在服务器)
- <button type="primary" bindtap="wx_login">
- 请求登录
- </button>
- <text class='text-red'>
- 当前 openid:{{openid}}
- </text>
接下来, 打开 index.JS, 在 page({}) 中插入下面的代码,
- wx_login() {
- var myThis = this;
- wx.login({
- success(res) {
- if (res.code) {
- wx.request({
- url: 'https:// 你服务器的请求地址',
- data: {
- code: res.code
- },
- success(res) {
- myThis.setData({
- openid: res.data.openid
- })
- }
- })
- } else {
- console.log('登录失败!' + res.errMsg)
- }
- }
- })
- },
之后, 你的页面可能如下所示, 注意, 代码中的 url 一定要更换为你服务器的地址, 并确保其通过 https 加密, 并在小程序开发者平台绑定, 关于如何加密绑定, 可以参考如何快速搭建微信小程序这篇文章. 代码中, 我们通过 wx.login() 中的 res.code 去获取当前的用户登录凭证 code, 然后通过 wx.request() 将 code 提交到你的服务器. 并等待返回结果 res.data.openid.
1541144650075
小程序端代码逻辑代码很简单, 接下来, 我们要撰写在服务端的代码.
服务器端
服务端的环境有很多选择 Node.JS,PHP,Python 等大部分主流语言都可以部署 HTTP 服务, 今天我们将教大家使用 PHP 语言进行环境部署, 其他语言请同学们自行部署.
安装环境
我这里以 Ubuntu Server 16.04 LTS 为例, 我们需要安装 PHP 运行环境及 Nginxweb 服务, 同时也需要申请免费的 SSL 证书和域名, 关于证书和域名的申请注册请参考如何快速搭建微信小程序这篇文章. 注册完域名及证书, 我们就可以开始部署服务器了! 首先, 登录服务器, 执行下面的命令.
- sudo apt update
- sudo apt install PHP PHP-fpm PHP-curl nginx -y
安装完成后, 使用浏览器访问你的服务器 IP 地址, 如果看到下面的内容, 则证明 Web 服务已经启动.
1541146155445
因为小程序获取远程数据, 必须为 HTTPS 环境, 所以目前搭建的环境, 在小程序无法使用, 接下来, 我们将使用 SSL 证书加密小程序访问你服务器之间的流量. 这里就需要刚才注册的域名及证书了. 首先, 将下载的证书, 上传到你的服务器, 并记录下这个位置. 然后, 我们将配置 Nginx 服务, 以让其支持 HTTPS 流量.
我们找到 / etc/nginx/conf.d 文件夹, 新建配置文件, 为了方便后续修改, 我将这里的配置文件修改为 weixin.techeek.cn.conf 大家可以根据自己的需求修改.
- cd /etc/nginx/conf.d
- sudo nano weixin.techeek.cn.conf
在 nano 编辑器中, 我们写下下面的代码
- server {
- listen 443 ssl;
- server_name weixin.techeek.cn;
- index index.PHP index.html index.htm;
- root /usr/share/nginx/HTML;
- ssl_certificate /home/Ubuntu/1_weixin.techeek.cn_bundle.crt;
- ssl_certificate_key /home/Ubuntu/2_weixin.techeek.cn.key;
- ssl_session_cache shared:SSL:1m;
- ssl_session_timeout 5m;
- ssl_ciphers HIGH:!aNULL:!MD5;
- ssl_prefer_server_ciphers on;
- location ~ .PHP$ {
- fastcgi_pass unix:/run/PHP/php7.0-fpm.sock;
- fastcgi_index index.PHP;
- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
- include fastcgi_params;
- }
- }
- server {
- listen 80 default_server;
- server_name weixin.techeek.cn;
- root /usr/share/nginx/HTML;
- index index.PHP index.HTML index.htm;
- location / {
- try_files $uri $uri/ =404;
- }
- }
一定注意, 将文中 server_name 中的 weixin.techeek.cn 更换成你的域名. 将 ssl_certificate 和 ssl_certificate_key 中证书的路径更换成你刚上传证书的路径. 然后, 执行下面的命令重启 nginx 服务.
sudo service nginx restart
之后, 打开你电脑的浏览器, 然后通过域名访问, 注意, 这里一定要在域名前加 https://, 比如我访问的域名 https://weixin.techeek.cn.
1541147802445
如果域名前有小锁标志, 则证明你已经配置成功, 可以开始下一步了.
运行环境
服务端已经配置完成, 接下来我们就需要撰写服务端代码了, 代码也很简单, 我们需要将其放在 / usr/share/nginx/HTML 这个目录下, 使用下面的命令.
- cd /usr/share/nginx/HTML
- sudo nano index.PHP
之后, 使用 nano 编辑器撰写下面的代码.
- <?PHP
- $code = $_GET["code"];
- $curl = curl_init();
- curl_setopt_array($curl, array(
- CURLOPT_URL => "https://api.weixin.qq.com/sns/jscode2session?appid=wx**********b&secret=0a6****************540&js_code=". $code ."&grant_type=authorization_code",
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_ENCODING => "",
- CURLOPT_MAXREDIRS => 10,
- CURLOPT_TIMEOUT => 30,
- CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
- CURLOPT_CUSTOMREQUEST => "GET",
- ));
- $response = curl_exec($curl);
- $err = curl_error($curl);
- curl_close($curl);
- if ($err) {
- echo "cURL Error #:" . $err;
- } else {
- echo $response;
- }
注意, 将代码中的 wx**********b 和 0a6****************540 替换为你在小程序管理页面获取到的 appid 和 AppSecret, 之后保存.(这段代码中, 为了方便演示, 我直接将 openid 和 session_key 等参数返回给了小程序, 如果你是在生产环境使用, 务必修改代码在服务端处理数据, 不要将原始的内容返回给小程序)
我们先通过浏览器测试下这段代码是否生效. 再次访问 https:// 你申请的域名, 如果看到类似下面的内容, 则代表服务器已经配置正确.
1541148529853
这里报错很正常, 因为我们没有将 code 参数通过浏览器传入我们搭建的微信服务器, 所以会报错. 接下来, 我们通过小程序去请求, 看看会发生什么.
获取 appid 和 session_key
现在, 请打开你微信开发者工具, 点击第一步我们编写好的代码环境中的请求登录按钮, 看看会发生什么.
1541148957224
系统会在微信小程序的界面自动返回当前开发者微信的 openid, 这个 openid 是唯一的, 每个微信用户获取到的都不同, 通过 openid, 我们就可以判断当前用户是否注册了你的小程序上面的业务. 现在点击开发者工具控制台中的 Nerwork 按钮, 我们看看刚才的请求是否成功.
1541149329853
我们看到, 系统发送了一个 HTTP 请求到 https://weixin.techeek.cn, 然后我们点击这个域名, 看看到底返回了什么样子的数据.
1541149428597
我们看到, 服务器返回了 openid 和当前 code 下的 session_key.
总结
本文详细介绍了小程序登录鉴权的流程, 后续如何存储 openid 和 session_key 这块是业务逻辑, 本文暂不涉及. session_key 主要用户后续解密小程序提供的开放数据, 后续文章中我们将对这部分做详细介绍, 并提供相关 Demo 做演示. 喜欢的小伙伴请持续关注本专栏 https://cloud.tencent.com/developer/column/72932 . 腾讯云联合小程序给大家带来了小程序. 云开发解决方案 https://cloud.tencent.com/solution/la , 为开发者提供完整的云端支持, 弱化后端和运维操作, 使用平台原生 API 进行核心业务开发, 实现快速上线和迭代. 欢迎免费使用!
来源: https://www.qcloud.com/developer/article/1360359