测试号
使用微信登陆获取到
- appId
- appsecret
填写服务器配置
验证消息的确来自微信服务器
配置URL 、Token用来响应微信发送的Token验证
服务器配置
文章底部有demo地址 微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:
| 参数 | 描述 |
|---|---|
| signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
| timestamp | 时间戳 |
| nonce | 随机数 |
| echostr | 随机字符串 |
本地开发配置
本地开发可以不需要后端配合的方式
准备服务器
- 自己写一个node服务器
- 使用上面配置的callback地址写一个get接口
- 接口实现不用严格根据接入指南中的验证,因为是本地配置直接返回成功和参数就好了
callback 接口代码
不验证正确性直接通过
export const checkSignature = (query) =>{
const {signature, timestamp, nonce, echostr} = query;
return echostr;
}
验证参数正确性
const config = require('config-lite')(__dirname);
import sha1 from 'crypto-js/sha1';
export const checkSignature = (query) =>{
const {signature, timestamp, nonce, echostr} = query;
const token = config.wxToken;
const tmpArr = [token, timestamp, nonce].sort();
//3.将三个参数字符串拼接成一个字符串进行sha1加密
var tempStr = tmpArr.join('');
const hashCode = sha1(tempStr).toString(); //创建加密类型
if(hashCode === signature){
// 对比加密是否一致
return echostr
}else {
return false
}
}
JS接口安全域名
配置好域名,可以在该域名下调用微信开放的JS接口
本地服务器生成 config
- 获取token
https请求方式: GET api.weixin.qq.com/cgi-bin/tok…
- 获取ticket
- 生成签名 signature
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
即signature=sha1(string1)。 示例:
noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value
步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
步骤2. 对string1进行sha1签名,得到signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
部分代码示例:
const config = require('config-lite')(__dirname);
import sha1 from 'crypto-js/sha1';
import http from '../../utils/http'
import {randomString} from '../../utils'
const {
token,
appId,
secret
} = config.wx;
let accessToken = ''; // 微信token
let accessTicket = ''; // 微信ticket
// 检查jsApi 回调
export const checkSignature = (query) => {
const {
signature,
timestamp,
nonce,
echostr
} = query;
const tmpArr = [token, timestamp, nonce].sort();
//3.将三个参数字符串拼接成一个字符串进行sha1加密
var tempStr = tmpArr.join('');
const hashCode = sha1(tempStr).toString(); //创建加密类型
if (hashCode === signature) {
// 对比加密是否一致
return echostr
} else {
return false
}
}
// 获取微信jsapi token
export const getToken = async () => {
if (accessToken !== '') {
return accessToken;
}
const res = await http.get('https://api.weixin.qq.com/cgi-bin/token', {
grant_type: 'client_credential',
appid: appId,
secret,
});
const {
access_token,
expires_in
} = res;
accessToken = access_token;
setTimeout(() => {
accessToken = '';
}, expires_in)
return accessToken;
}
// 获取微信jsAPI ticket
export const getTicket = async (accessToken) => {
if (!accessToken) {
throw new Error('access_token 不能为空');
}
const res = await http.get('https://api.weixin.qq.com/cgi-bin/ticket/getticket', {
access_token: accessToken,
type: 'jsapi',
});
const {
errcode,
ticket,
expires_in,
errmsg
} = res;
if (errcode === 0) {
accessTicket = ticket;
setTimeout(() => {
accessTicket = '';
}, expires_in)
} else {
throw new Error(`获取ticket失败 ${errcode}: ${errmsg}`)
}
return accessTicket;
}
// 获取微信配置
export const getConfig = async (query) => {
const token = await getToken();
const ticket = await getTicket(token);
const {
url
} = query;
const nonceStr = randomString(16);
const timestamp = ~~(new Date() / 1000);
const str = `jsapi_ticket=${ticket}&noncestr=${nonceStr}×tamp=${timestamp}&url=${url}`
const signature = sha1(str).toString();
return {
signature,
timestamp,
nonceStr,
appId,
}
}
本地开发配置
- host 本地域名指向修改(域名规则要匹配前面配置的安全域名)
- vue.config.js devserve public 要改成host指向的域名
- 可以使用微信开发者工具进行本地开发测试