⼿把⼿实现⽹页授权和⽀付,附源代码
(VUEandthinkPHP)
wechat
⼿把⼿实现⽹页授权和⽀付,附源代码(VUE and thinkPHP)
概述
开发是痛苦的,痛苦在好多问题开发者⽂档是没有提到的,是需要你猜的. 在开发过程中翻了好多的⽂档,都是说明其中的⼀部分问题的,很费时间,所以在此总结⼤体过程。我们模拟的是⼀个⽀付的商城,在实现购买过程中基本是把最主要模块实现了,其余的功能我们没有涉及,但应该是触类旁通的。
我们叙述的过程是按开发流程进⾏叙述的,不会是按照开发⽂档的形式叙述,希望您能结合⼀起阅读,当然在流程中我们会提醒你阅读的部分
⽬录
[解决的问题]
[前端技术栈]
[后端技术栈]
[基本说明]
[开发过程]
[0.准备]
[1.基本配置]
[2.⽹页授权]
[签名]
[签名后台]
[签名前台]
[⽀付]
解决的问题
[x] ⽹页授权
[x] ⽀付
[x] 分享
[x] 扫⼀扫
[x] 后台获取webapp(spa-vue)路由,导致 invalid 问题
[x] 前端history.pushState()导致ios失效问题
[x] 换取openID 顺序问题
[x] ⽹页授权后强制登录官⽹账户,全局进⾏拦截
前端技术栈
vue2 + vuex + vue-router + webpack + ES6/7 + axios + sass + flex
后端技术栈
thinkPHP3.2 + mysql + 阿⾥云Linux Ubuntu
基本说明
开发环境 macOS 10.13.3  nodejs 8.0.0 centOS 7.4
本⽂中使⽤的url是m.example (demo), 开发过程中需要替换成你的URL。
如有问题请直接在 Issues 中提,或者您发现问题并有⾮常好的解决⽅案,欢迎 PR
本着线上线下⼀样的原则,最好申请两个认证,⼀个是发布使⽤,⼀个是本地开发使⽤。⾃带提供的测试功能也不太好⽤
可以添加流 544958637
开发过程
0.准备
请阅读以下开发者⽂档
附:参数说明
appid:唯⼀标识id(-开发-基本配置中查看)。
secret:开发密钥(初次请保存本地,忘记请重置)。
openid: 每个⽤户关注此后会⽣成openid,并且在此中每个⽤户得openid是唯⼀的。
code : code作为换取access_token的票据,每次⽤户授权带上的code将不⼀样,code只能使⽤⼀次,5分钟未被使⽤⾃动过期。
IP ⽩名单:允许访问服务器的ip(linux 公⽹ip 注意如果服务器有CDN加速,CDN请添加⽩名单)
1.基本配置
此部分对应⽂档的
1. 基础⼯具
1. ⼀个已经认证的(就是你已经交300元)
2. 已经备案的域名
3. 域名解析到服务器 传送门
4. : 开发可定使⽤这个⼯具。必须把前端代码放到》服务器上》⽤这个⼯具调试。请仔细阅读
2. 设置web开发者⼯具
在开发-开发者⼯具-web开发者⼯具设置开发者账号
3. 设置IP ⽩名单
在设置-安全中⼼-IP⽩名单设置你服务器的IP,通过开发者ID及密码调⽤获取access_token接⼝时,需要设置访问来源IP为⽩名单。
4. 设置基本配置-开发者ID
设置开发者密码(AppSecret)
我们获取到的AppSecret (eg) a66b789009df271cde47aaaaaaa
5. 设置服务器基本配置
这部的⽬的是为了和服务器建⽴联系, 通过平台实现我们的业务逻辑。
详细版:
![image](//upload-images.jianshu.io/upload_images/2491178-87d4e2f74ea3da4b?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
接⼊公众平台开发,开发者需要按照如下步骤完成:
1、填写服务器配置
2、验证服务器地址的有效性
3、依据接⼝⽂档实现业务逻辑
下⾯详细介绍这3个步骤。
**第⼀步:填写服务器配置**
* 登录公众平台官⽹后,在公众平台官⽹的开发-基本设置页⾯,勾选协议成为开发者,点击“修改配置”按钮、。
* 填写服务器地址(URL)、Token和EncodingAESKey
* URL是开发者⽤来接收消息和事件的接⼝URL。
* Token可由开发者可以任意填写,⽤作⽣成签名(该Token会和接⼝URL中包含的Token进⾏⽐对,从⽽验证安全性)
* EncodingAESKey由开发者⼿动填写或随机⽣成,将⽤作消息体加解密密钥。
* 同时,开发者可选择消息加解密⽅式:明⽂模式、兼容模式和安全模式。模式的选择与服务器配置在提交后都会⽴即⽣效
* 加解密⽅式的默认状态为明⽂模式,选择兼容模式和安全模式需要提前配置好相关加解密代码
第⼆步:验证消息的确来⾃服务器
现在如果你点击确认 按钮,肯定会报认证错误。因为我们没有做认证请求 接收。 开发者提交信息后,服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所⽰:
参数描述
signature加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp时间戳
nonce随机数
echostr随机字符串
开发者通过检验signature对请求进⾏校验(下⾯有校验⽅式)。若确认此次GET请求来⾃服务器,请原样返回echostr参数内容,则接⼊⽣效,成为开发者成功,否则接⼊失败。加密/校验流程如下:
1. 将token、timestamp、nonce三个参数进⾏字典序排序
2. 将三个参数字符串拼接成⼀个字符串进⾏sha1加密
3. 开发者获得加密后的字符串可与signature对⽐,标识该请求来源于
官⽅提供在⽂档中提供了PHP原⽣⽰例
Thinkphp 3.2 验证⽰例
<?php
namespace Home\Controller;//命名空间注意⽤⾃⼰的
use Think\Controller; //引⼊Think Controller
/**
* Class IndexController
* @package Home\Controller
* @name 服务器验证类
* @author weikai
*/
class IndexController extends Controller {
//服务器接⼊
public function index()
{
//这个echostr呢只有说验证的时候才会echo  如果是验证过之后这个echostr是不存在的字段了
8.0怎么更新if($_GET['echostr']){
$echoStr = $_GET["echostr"];
if ($this->checkSignature()) {
ob_clean();//防⽌之前缓存区数据影响
echo $echoStr;
exit;
}
}else{
$this->responseMsg(); //如果没有echostr,则返回消息
}
}
//验证开发者模式接⼊是否成功
private function checkSignature()
{
//signature 是传过来的签名
$signature = $_GET["signature"];
//发过来的时间戳
$timestamp = $_GET["timestamp"];
//传过来的值随机字符串
$nonce    = $_GET["nonce"];
//定义你在开发者模式⾥⾯定义的token 这⾥举例为weixin
$token  = "weixin";
//三个变量按照字典排序形成⼀个数组
$tmpArr = array(
$token,
$timestamp,
$nonce
);
// 字典排序
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
//哈希加密在laravel⾥⾯是Hash::
$tmpStr = sha1($tmpStr);
//哈希加密后的数据和服务器传过来的签名⽐较
if ($tmpStr == $signature) {
return true;
} else {
return false;
}
}
/**
* @name 消息接收
* @author weikai
*/
public function responseMsg()//执⾏接收器⽅法
{
//获取服务器的XML数据转化为对象判断消息类型
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
if (!empty($postStr)){
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$RX_TYPE = trim($postObj->MsgType);
switch($RX_TYPE){
case "event":
$result = $this->receiveEvent($postObj);
break;
case "text":
$result = $this->handleText($postObj);
break;
}
echo $result;
}else{
echo "";
exit;
}
}
} //classend
注意:⽰例代码中 Token 要与基本配置中的Token ⼀致
基本配置中点击启⽤配置,如果验证失败可能是⽹络延迟导致,再点击启⽤多试⼏次,3次以上不成功,请检查代码。
2.⽹页授权
如果使⽤⽀付功能,必须先授权
⼤家应该经历过,我们在打开页⾯,⼀般都会弹出⼀个按钮需要我们点击同意才会继续浏览页⾯