前端 | 微信小程序开发工具 |
---|---|
后端 | idea 2018.3 +mysql8.0 |
ps:因为我是后端开发 所以只能写后端。。
邮箱注册微信公众平台小程序 !!! 着重强调 是小程序注册 !!!
注册链接:微信公众平台
注册完成之后 ,在开发-开发设置里边可以看到appid和secret,注册的目的就是为了获取这两个参数,以为了向微信服务器发送请求
因为微信平台的要求,需要用http:或者https:开头的合法域名,我这里采用的是natapp 购买的隧道,类似于服务器+域名(9RMB一个月,作为调试开发还是可以的) ,然后将域名配置到微信的开发-开发设置里边
这里需要注意的是:前端访问的域名不能是服务器ip+端口号+接口名的方式,是要以这个request合法域名+接口名发送请求,否则请求不能发送到微信服务器端
因为前端的同学跟我是第一次开发微信小程序,登录获取用户授权页面有点简陋,就不发wxml了(微信版html)
// pages/indxe/login/login.js
Page({
/**
* 页面的初始数据
*/
data: {
},
getUserInfoBtn:function(){
wx.login({
success:function(data){
var code=data.code
wx.getUserInfo({
success:function(res){
var userInfor=res
var rawData=res.rawData
var iv=res.iv
var encryptedData = res.encryptedData
console.log(encryptedData)
wx.request({
url:'//微信要求的合法域名+后端请求接口'
data: {
iv: iv,
encryptedData: encryptedData,
code: code
},
header: {
'content-type': 'application/json' //默认值
},
success: function (res) {
console.log(res.data)
}
})
}
})
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
http://wechatapptest.natapp1.cc/takeaway/user/login',
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
spring:
datasource:
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/takeaway_applet?useSSL=false&characterEncoding=utf-8
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 50
# 获取连接等待超时的时间
max-wait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 300000
mybatis:
mapper-locations: classpath:mappers/*.xml
type-aliases-package: com.swpu.uchain.takeawayapplet.entity
configuration:
map-underscore-to-camel-case: true
use-generated-keys: true
file:
upload-dir: "/home/hobo/testFile"
#微信端配置
wechat:
appid: wx08cbe6a7723b4059
secret: 184d33fb3de278d49a1411cd111eeaa2
/**
* @ClassName WeChatAccountConfig
* @Author hobo
* @Date 19-3-8 下午9:49
* @Description
**/
@Data
@ConfigurationProperties(prefix = "wechat")
@Component
public class WeChatProperties {
/**
* 微信小程序appId
*/
private String appid;
/**
* 微信小程序的Secret
*/
private String secret;
/**
* 微信小程序消息服务器配置的token
*/
private String token;
/**
* 设置微信小程序消息服务器配置的EncodingAESKey
*/
private String aesKey;
/**
* 消息格式,XML或者JSON
*/
private String msgDataFormat;
/**
* 开放平台id
*/
private String openAppId;
/***
* 开放平台秘钥
*/
private String openAppSecret;
/**
* 商户号
*/
private String mchId;
/**
* 商户密钥
*/
private String mchKey;
/**
* 商户证书路径
*/
private String keyPath;
/**
* 微信异步通知地址
*/
private String notifyUrl;
/**
* 商品简单描述
*/
private String title;
/**
* 支付类型 小程序为JSAPI
*/
private String tradeType;
}
PS: 微信小程序登录分为两种,一种是前端在发送登录请求时,随机发送code,不需要用户授权,这种方式只获得用户的openId,另一种方式是从微信端发来iv,encryptedData,code。后端经过算法解密处理得到用户的一些信息,包括微信昵称及头像等等,我这次是采用了后者。根据前端代码大家也可以看出前端是传了这三个参数的。
@ApiOperation("普通用户登录授权接口")
@GetMapping(value = "/login", name = "普通用户登录")
public Object getUserInfo(String encryptedData, String iv, String code) {
Map map = new HashMap();
if (code == null) {
return ResultUtil.error(ResultEnum.CODE_EMPTY);
}
//微信登录请求URL
String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + weChatProperties.getAppid() + "&secret=" + weChatProperties.getSecret() + "&js_code=" + code + "&grant_type=authorization_code";
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject(url, String.class);
//将Json对象转换为Java对象
WeChatVO weChatVO = JSONObject.parseObject(response, WeChatVO.class);
String openId = weChatVO.getOpenId();
String sessionKey = weChatVO.getSessionKey();
//解密用户信息
String result = AesCbcUtil.decrypt(encryptedData, sessionKey, iv, "UTF-8");
if (null != result && result.length() > 0) {
//ResultUtil是我自定义的Json化工具类
return ResultUtil.success(result);
}
return ResultUtil.error(ResultEnum.DECRYPTION_FAILURE);
}
需要引入bcprov-ext-jdk16的依赖
org.bouncycastle
bcprov-ext-jdk16
1.46
jar
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;
/**
* @ClassName AesCbcUtil
* @Author hobo
* @Date 19-3-15 下午3:15
* @Description 用于用户解密
**/
public class AesCbcUtil {
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* @return java.security.Security
* @Author hobo
* @Description : AES解密
* @Param data //密文 加密的数据
* @Param key //秘钥
* @Param iv //偏移量
* @Param encodingFormat //解密后结果的编码格式
**/
public static String decrypt(String data, String key, String iv, String encodingFormat) {
byte[] dataByte = Base64.decodeBase64(data);
byte[] keyByte = Base64.decodeBase64(key);
byte[] ivByte = Base64.decodeBase64(iv);
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
parameters.init(new IvParameterSpec(ivByte));
cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
byte[] resultByte = cipher.doFinal(dataByte);
if (null != resultByte && resultByte.length > 0) {
String result = new String(resultByte, encodingFormat);
return result;
}
return null;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidParameterSpecException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}
{"openId":"oFVAK4_iFtKuKDMpzEfAfjeI6ysQ","nickName":"菜逼玉","gender":1,"language":"zh_CN","city":"Chengdu","province":"Sichuan","country":"China","avatarUrl":"https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTL94p6V7YgKUP2r9X4mLibwblyib3YAicRG54qAw2EEz0dO2ibMBLSnMqcm2CichAd3yZ36ZjBbMAdh7Wg/132","watermark":{"timestamp":1553434671,"appid":"wx08cbe6a7723b4059"}}
可以看到 我的微信的个人信息已经获得
github上边有sdk可以用微信开发者联盟,但发现自己能力不足,只能用原生的方法。
大家在开发前一定要看小程序开发Api,不然会踩大坑。
新人第一篇博客 QQ:1056024860 敬候志同道合的同学跟我一起探讨微信开发