-
微信小程序java后端代码
2018-04-08 10:16:30微信小程序java后端代码 -
微信小程序java后台代码(服务端)demo
2017-11-29 18:42:23微信小程序java后台代码(服务端)demo -
微信小程序java解密demospringboot-weapp-demo-master.zip
2019-09-25 20:24:30微信小程序java解密demospringboot-weapp-demo-master.zip -
基于微信小程序JAVA后端代码
2019-12-27 14:09:30微信小程序后端代码,简单的后台程序,基于SPRINGBOOT搭建的后台程序,前端发送请求,后台响应............... -
微信小程序 java设置cookie登录
2019-07-25 15:12:43微信小程序 java设置cookie登录 wx.request()发起的每次请求对于服务器来说都是不同的会话 这样导致后续请求都相当于未登录的状态。 app.js globalData: { url: ‘http://127.0.0.1:8080’, cookie: “”, }, 后台 @...微信小程序 java设置cookie登录
wx.request()发起的每次请求对于服务器来说都是不同的会话 这样导致后续请求都相当于未登录的状态。
app.js
globalData: {
url: ‘http://127.0.0.1:8080’,
cookie: “”,},
后台@PostMapping(“sessionId”)
@ResponseBody`public String sessionId( HttpServletRequest request){ String sessionId=request.getSession().getId(); return sessionId; }
返回给前台
前台在请求的回调中给全局的参数cookie赋值onLoad: function(options) { wx.request({ url: url, method: 'post', success(res) { app.globalData.cookie = 'JSESSIONID=' + res.data console.log(app.globalData.cookie) } }) },
然后在每次请求request的header中添加
header: { ...., 'cookie': getApp().globalData.cookie },
-
微信小程序Java登录流程
2018-05-10 15:05:04一、登录流程图二、微信小程序端doLogin:function(callback = () =>{}){ let that = this; wx.login({ success:function(loginRes){ if(loginRes){ //获取用户信息 wx.getUserInfo({ withCredentials:...一、登录流程图
二、微信小程序端
doLogin:function(callback = () =>{}){ let that = this; wx.login({ success:function(loginRes){ if(loginRes){ //获取用户信息 wx.getUserInfo({ withCredentials:true,//非必填 默认为true success:function(infoRes){ console.log(infoRes,'>>>'); //请求服务端的登录接口 wx.request({ url: api.loginUrl, data:{ code:loginRes.code,//临时登录凭证 rawData:infoRes.rawData,//用户非敏感信息 signature:infoRes.signature,//签名 encrypteData:infoRes.encryptedData,//用户敏感信息 iv:infoRes.iv//解密算法的向量 }, success:function(res){ console.log('login success'); res = res.data; if(res.result==0){ that.globalData.userInfo = res.userInfo; wx.setStorageSync('userInfo',JSON.stringify(res.userInfo)); wx.setStorageSync('loginFlag',res.skey); console.log("skey="+res.skey); callback(); }else{ that.showInfo('res.errmsg'); } }, fail:function(error){ //调用服务端登录接口失败 // that.showInfo('调用接口失败'); console.log(error); } }); } }); }else{ } } }); }
微信小程序端发起登录请求,携带的参数主要有:
code:loginRes.code,//临时登录凭证 rawData:infoRes.rawData,//用户非敏感信息 signature:infoRes.signature,//签名 encrypteData:infoRes.encryptedData,//用户敏感信息 iv:infoRes.iv//解密算法的向量
需要的数据主要有:
result、userInfo和skey
result用来判断是否登录成功,userInfo是用户的一些信息,保存在缓存中,不用每次都从后台获取,skey是用户登录态标识,也放在缓存中,如果skey存在就直接登录,维护用户的登录状态,具有时效性
三、Java后台
@ResponseBody @RequestMapping("/login") public Map<String,Object> doLogin(Model model, @RequestParam(value = "code",required = false) String code, @RequestParam(value = "rawData",required = false) String rawData, @RequestParam(value = "signature",required = false) String signature, @RequestParam(value = "encrypteData",required = false) String encrypteData, @RequestParam(value = "iv",required = false) String iv){ log.info( "Start get SessionKey" ); Map<String,Object> map = new HashMap<String, Object>( ); System.out.println("用户非敏感信息"+rawData); JSONObject rawDataJson = JSON.parseObject( rawData ); System.out.println("签名"+signature); JSONObject SessionKeyOpenId = getSessionKeyOrOpenId( code ); System.out.println("post请求获取的SessionAndopenId="+SessionKeyOpenId); String openid = SessionKeyOpenId.getString("openid" ); String sessionKey = SessionKeyOpenId.getString( "session_key" ); System.out.println("openid="+openid+",session_key="+sessionKey); User user = userService.findByOpenid( openid ); //uuid生成唯一key String skey = UUID.randomUUID().toString(); if(user==null){ //入库 String nickName = rawDataJson.getString( "nickName" ); String avatarUrl = rawDataJson.getString( "avatarUrl" ); String gender = rawDataJson.getString( "gender" ); String city = rawDataJson.getString( "city" ); String country = rawDataJson.getString( "country" ); String province = rawDataJson.getString( "province" ); user = new User(); user.setUid( openid ); user.setCreateTime( new Date( ) ); user.setSessionkey( sessionKey ); user.setUbalance( 0 ); user.setSkey( skey ); user.setUaddress( country+" "+province+" "+city ); user.setUavatar( avatarUrl ); user.setUgender( Integer.parseInt( gender ) ); user.setUname( nickName ); user.setUpdateTime( new Date( ) ); userService.insert( user ); }else { //已存在 log.info( "用户openid已存在,不需要插入" ); } //根据openid查询skey是否存在 String skey_redis = (String) redisTemplate.opsForValue().get( openid ); if(StringUtils.isNotBlank( skey_redis )){ //存在 删除 skey 重新生成skey 将skey返回 redisTemplate.delete( skey_redis ); } // 缓存一份新的 JSONObject sessionObj = new JSONObject( ); sessionObj.put( "openId",openid ); sessionObj.put( "sessionKey",sessionKey ); redisTemplate.opsForValue().set( skey,sessionObj.toJSONString() ); redisTemplate.opsForValue().set( openid,skey ); //把新的sessionKey和oppenid返回给小程序 map.put( "skey",skey ); map.put( "result","0" ); JSONObject userInfo = getUserInfo( encrypteData, sessionKey, iv ); System.out.println("根据解密算法获取的userInfo="+userInfo); userInfo.put( "balance",user.getUbalance() ); map.put( "userInfo",userInfo ); return map; }
获取openid和sessionKey方法
public static JSONObject getSessionKeyOrOpenId(String code){ //微信端登录code String wxCode = code; String requestUrl = "https://api.weixin.qq.com/sns/jscode2session"; Map<String,String> requestUrlParam = new HashMap<String, String>( ); requestUrlParam.put( "appid","你的小程序appId" );//小程序appId requestUrlParam.put( "secret","你的小程序appSecret" ); requestUrlParam.put( "js_code",wxCode );//小程序端返回的code requestUrlParam.put( "grant_type","authorization_code" );//默认参数 //发送post请求读取调用微信接口获取openid用户唯一标识 JSONObject jsonObject = JSON.parseObject( UrlUtil.sendPost( requestUrl,requestUrlParam )); return jsonObject; }
解密用户敏感数据获取用户信息
public static JSONObject getUserInfo(String encryptedData,String sessionKey,String iv){ // 被加密的数据 byte[] dataByte = Base64.decode(encryptedData); // 加密秘钥 byte[] keyByte = Base64.decode(sessionKey); // 偏移量 byte[] ivByte = Base64.decode(iv); try { // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 int base = 16; if (keyByte.length % base != 0) { int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyByte, 0, temp, 0, keyByte.length); keyByte = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC"); 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, "UTF-8"); return JSON.parseObject(result); } } catch (NoSuchAlgorithmException e) { log.error(e.getMessage(), e); } catch (NoSuchPaddingException e) { log.error(e.getMessage(), e); } catch (InvalidParameterSpecException e) { log.error(e.getMessage(), e); } catch (IllegalBlockSizeException e) { log.error(e.getMessage(), e); } catch (BadPaddingException e) { log.error(e.getMessage(), e); } catch (UnsupportedEncodingException e) { log.error(e.getMessage(), e); } catch (InvalidKeyException e) { log.error(e.getMessage(), e); } catch (InvalidAlgorithmParameterException e) { log.error(e.getMessage(), e); } catch (NoSuchProviderException e) { log.error(e.getMessage(), e); } return null; }
四、流程
1.小程序端发起请求并携带主要参数
2.java后台接到/login请求后,根据code去调用微信接口获取用户唯一标识openid和sessionKey
3.根据openid查询mysql数据库,判断该用户是否存在,如果不存在将用户非敏感信息和其他初始化数据存入到数据库中,如果已存在,不操作
4.根据openid查询redis数据库,判断openid对应的skey是否存在,如果存在则删除原来老的skey以及对应的openid和sessionKey
5.通过uuid生成唯一的skey,用openid做键,skey做值,存入到redis中
6.然后把skey做键,openid和sessionKey的json串做值也重新存入到redis中
7.根据解密算法,参数有encryptedData、sessionKey和iv,获取用户信息userInfo,如果userInfo字段不满足需要,可通过userInfo.put( "balance",user.getUbalance() );添加所需要的字段和值
8.将微信小程序需要的数据封装到map中,返回给小程序端
map.put( "skey",skey ); map.put( "result","0" ); map.put( "userInfo",userInfo ); return map;
-
微信小程序java上传图片_servlet
2019-01-28 20:55:24有助于写微信小程序的小伙伴们 进行前端与后端的交互的代码。 -
微信小程序java后台解码获取信息
2018-01-24 13:44:28微信小程序java后台解码获取信息 由于小程序开发多个地方都需要使用到解码获取信息的需求,但由于本人从事java的开发然后去官网下载的sdk中竟然没有java的。哎-_-。所以准备写一篇关于java解码的blog吧。 一、...微信小程序java后台解码获取信息
由于小程序开发多个地方都需要使用到解码获取信息的需求,但由于本人从事java的开发然后去官网下载的sdk中竟然没有java的。哎-_-。所以准备写一篇关于java解码的blog吧。
一、我们解码前需要获取到几个小程序前端传过来的数据
登录凭证code:调用wx.login()可以获得;
秘钥iv和需要解码的encryptedData字符串:这个根据自己项目的需求定了,比如:获取openid和unionid可以在 wx.getUserInfo()中获得iv和encryptedData。
如果获取微信群ID:则通过wx.getShareInfo()获得iv和encryptedData。
微信小程序前端这里就不做详细的分析了。二 、 java后端的实现
/** * 获取微信群ID(Gid) * data:2018/1/24 * @return * @throws Exception */ public String wxGetGroupGid() throws Exception{ String code=request.getParameter("code");接受小程序传过来的登录凭证code, String iv=request.getParameter("iv"); String encryptedData=request.getParameter("encryptedData"); String OPENID_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret" + "=SECRET&js_code=JSCODE&grant_type=authorization_code";// 获取openid的地址 String url = OPENID_URL.replace("APPID", Pkcs7Encoder.APPID) .replace("SECRET", Pkcs7Encoder.APPSECRET) .replace("JSCODE", code); JSONObject jsonObject = null; //向微信后台发起请求的url jsonObject = Pkcs7Encoder.doGetStr(url);// 调取Get提交方法 String session_key = jsonObject.getString("session_key"); String result = Pkcs7Encoder.decrypt(encryptedData, session_key, iv, "UTF-8"); JSONObject userInfoJSON = JSONObject.fromObject(result); String openGid=userInfoJSON.getString("openGId"); System.out.println(openGid); String JData="{\"openGid\":\""+openGid+"\"}"; //response.getWriter().write(openGid); Struts2Utils.renderJsonNoDown(response, JData); return null; }
解码的帮助类
public class Pkcs7Encoder { public final static String APPID = "***"; //小程序的APPID public final static String APPSECRET = "***"; //小程序的appsecret public final static String grant_type = "authorization_code";//授权(必填) // 算法名称 static final String KEY_ALGORITHM = "AES"; // 加解密算法/模式/填充方式 static final String algorithmStr = "AES/CBC/PKCS7Padding"; private static Key key; private static Cipher cipher; boolean isInited = false; //默认对称解密算法初始向量 iv static byte[] iv = { 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38 }; public static String decrypt(String encryptedData, String sessionKey, String iv, String encodingFormat) throws Exception { // 被加密的数据 byte[] dataByte = Base64.decode(encryptedData); // 加密秘钥 byte[] keyByte = Base64.decode(sessionKey); // 偏移量 byte[] ivByte = Base64.decode(iv); try { // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 int base = 16; if (keyByte.length % base != 0) { int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyByte, 0, temp, 0, keyByte.length); keyByte = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); 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, "UTF-8"); return JSONObject.fromObject(result).toString(); } }catch (Exception e) { e.printStackTrace(); } return null; } /** * 返回openid,unionid * @param url * @return */ public static JSONObject doGetStr(String url){ DefaultHttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); JSONObject jsonObject = null; try { HttpResponse response = httpClient.execute(httpGet); HttpEntity entity = response.getEntity(); //接受结果 if(entity != null){ String result = EntityUtils.toString(entity,"UTF-8"); jsonObject = JSONObject.fromObject(result); } } catch (IOException e) { e.printStackTrace(); } return jsonObject; } public static void init(byte[] keyBytes) { // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 int base = 16; if (keyBytes.length % base != 0) { int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length); keyBytes = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); // 转化成JAVA的密钥格式 key = new SecretKeySpec(keyBytes, KEY_ALGORITHM); try { // 初始化cipher cipher = Cipher.getInstance(algorithmStr, "BC"); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchPaddingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchProviderException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 加密方法 * --使用默认iv时 * @param content * 要加密的字符串 * @param keyBytes * 加密密钥 * @return */ public static byte[] encrypt(byte[] content, byte[] keyBytes) { byte[] encryptedText = encryptOfDiyIV(content,keyBytes,iv); return encryptedText; } /** * 解密方法 * --使用默认iv时 * @param encryptedData * 要解密的字符串 * @param keyBytes * 解密密钥 * @return */ public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes) { byte[] encryptedText = decryptOfDiyIV(encryptedData,keyBytes,iv); return encryptedText; } /** * 加密方法 * ---自定义对称解密算法初始向量 iv * @param content * 要加密的字符串 * @param keyBytes * 加密密钥 * @param ivs * 自定义对称解密算法初始向量 iv * @return 加密的结果 */ public static byte[] encryptOfDiyIV(byte[] content, byte[] keyBytes, byte[] ivs) { byte[] encryptedText = null; init(keyBytes); System.out.println("IV:" + new String(ivs)); try { cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivs)); encryptedText = cipher.doFinal(content); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return encryptedText; } /** * 解密方法 * * @param encryptedData * 要解密的字符串 * @param keyBytes * 解密密钥 * @param ivs * 自定义对称解密算法初始向量 iv * @return */ public static byte[] decryptOfDiyIV(byte[] encryptedData, byte[] keyBytes,byte[] ivs) { byte[] encryptedText = null; init(keyBytes); System.out.println("IV:" + new String(ivs)); try { cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivs)); encryptedText = cipher.doFinal(encryptedData); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return encryptedText; } /** * 向指定 URL 发送POST方法的请求 * * @param url 发送请求的 URL * @param param 请求参数 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, Map<String, ?> paramMap) { PrintWriter out = null; BufferedReader in = null; String result = ""; String param = ""; Iterator<String> it = paramMap.keySet().iterator(); while(it.hasNext()) { String key = it.next(); param += key + "=" + paramMap.get(key) + "&"; } try { URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("Accept-Charset", "utf-8"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(param); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { e.printStackTrace(); } //使用finally块来关闭输出流、输入流 finally{ try{ if(out!=null){ out.close(); } if(in!=null){ in.close(); } } catch(IOException ex){ ex.printStackTrace(); } } return result; } }
只要涉及到小程序解码的都是通用的,所以到这里已经完成了。
-
微信小程序java登录授权解密获取unionId
2019-07-10 18:54:45微信小程序java登录授权解密获取unionId(填坑) 2018年08月03日 16:00:18 人类电影精华丶 阅读数 4041 官方流程图: 第一步:获取code 说明: 小程序调用wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。 ...微信小程序java登录授权解密获取unionId(填坑)
2018年08月03日 16:00:18 人类电影精华丶 阅读数 4041
官方流程图:第一步:获取code
说明:
小程序调用wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
开发者服务器以code换取 用户唯一标识openid 和 会话密钥session_key。
之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。
//app.js
App({
onLaunch: function() {
wx.login({
success: function(res) {
if (res.code) {
//发起网络请求
wx.request({
url: ‘https://test.com/onLogin’,
data: {
code: res.code
}
})
} else {
console.log(‘登录失败!’ + res.errMsg)
}
}
});
}
})关于unionId,这里需要说明一下,如果应用只限于小程序内则不需要unionId,直接通过openId可以确定用户身份,但是如果需要跨应用 如:网页应用,app应用时则需要使用到unionId作为身份标识。
UnionID获取途径
绑定了开发者帐号的小程序,可以通过下面3种途径获取UnionID。
调用接口wx.getUserInfo,从解密数据中获取UnionID。注意本接口需要用户授权,请开发者妥善处理用户拒绝授权后的情况。
如果开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号。开发者可以直接通过wx.login获取到该用户UnionID,无须用户再次授权。
如果开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用。开发者也可以直接通过wx.login获取到该用户UnionID,无须用户再次授权。
说明完了,我们继续下一步,主要需要区分获得授权,和未获得授权情况
第二步:通过code换取sessionKey等个人信息
1、未获得授权
注意:这里unionId如果满足上面2、3所说获取条件,则会在这一步里返回,如果不满足则需要调用wx.getUserInfo来获取,这个方法需要获得用户授权。
public class Test {
private static final String APPID = "";// 微信应用唯一标识 private static final String SECRET = ""; public void main(String code) { JSONObject jsonObject = code2sessionKey(code); String openId = jsonObject.getString("openid");// 用户唯一标识 String session_key = jsonObject.getString("session_key");// 密钥 // 满足UnionID下发条件的情况下,返回 String unionId = jsonObject.getString("unionid"); } /** * 发送请求用code换取sessionKey和相关信息 * * @param code * @return */ public static JSONObject code2sessionKey(String code) { String stringToken = String.format( "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", APPID, SECRET, code); String response = HttpUtils.httpsRequestToString(stringToken, "GET", null); return JSON.parseObject(response); } /** * 发送https请求 * * @param path * @param method * @param body * @return */ public static String httpsRequestToString(String path, String method, String body) { if (path == null || method == null) { return null; } String response = null; InputStream inputStream = null; InputStreamReader inputStreamReader = null; BufferedReader bufferedReader = null; HttpsURLConnection conn = null; try { // 创建SSLConrext对象,并使用我们指定的信任管理器初始化 SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); TrustManager[] tm = { new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } }; sslContext.init(null, tm, new java.security.SecureRandom()); // 从上面对象中得到SSLSocketFactory SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(path); conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(ssf); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); // 设置请求方式(get|post) conn.setRequestMethod(method); // 有数据提交时 if (null != body) { OutputStream outputStream = conn.getOutputStream(); outputStream.write(body.getBytes("UTF-8")); outputStream.close(); } // 将返回的输入流转换成字符串 inputStream = conn.getInputStream(); inputStreamReader = new InputStreamReader(inputStream, "UTF-8"); bufferedReader = new BufferedReader(inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } response = buffer.toString(); } catch (Exception e) { } finally { if (conn != null) { conn.disconnect(); } try { bufferedReader.close(); inputStreamReader.close(); inputStream.close(); } catch (IOException execption) { } } return response; }
}
2、获得授权情况下
当前台获得了用户的授权后,我们就可以获得用户的个人信息以及unionId(不管有没有关注公众号)
前台接口:
wx.getUserInfo(OBJECT)
注意:此接口有调整,使用该接口将不再出现授权弹窗,请使用 引导用户主动进行授权操作当用户未授权过,调用该接口将直接报错
当用户授权过,可以使用该接口获取用户信息
OBJECT参数说明:参数名 类型 必填 说明 最低版本
withCredentials Boolean 否 是否带上登录态信息 1.1.0
lang String 否 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。默认为en。 1.3.0
timeout Number 否 超时时间,单位 ms 1.9.90
success Function 否 接口调用成功的回调函数
fail Function 否 接口调用失败的回调函数
complete Function 否 接口调用结束的回调函数(调用成功、失败都会执行)
注:当 withCredentials 为 true 时,要求此前有调用过 wx.login 且登录态尚未过期,此时返回的数据会包含 encryptedData, iv 等敏感信息;当 withCredentials 为 false 时,不要求有登录态,返回的数据不包含 encryptedData, iv 等敏感信息。success返回参数说明:
参数 类型 说明
userInfo OBJECT 用户信息对象,不包含 openid 等敏感信息
rawData String 不包括敏感信息的原始数据字符串,用于计算签名。
signature String 使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息,参考文档 signature。
encryptedData String 包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法
iv String 加密算法的初始向量,详细见加密数据解密算法示例代码:
授权登录
请升级微信版本
//js
Page({
data: {
canIUse: wx.canIUse(‘button.open-type.getUserInfo’)
},
onLoad: function() {
// 查看是否授权
wx.getSetting({
success: function(res){
if (res.authSetting[‘scope.userInfo’]) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称
wx.getUserInfo({
success: function(res) {
console.log(res.userInfo)
}
})
}
}
})
},
bindGetUserInfo: function(e) {
console.log(e.detail.userInfo)
}
})
前台调用getUserInfo后,可以将获得的code值,encryptedData加密数据包,iv初始向量提示发给后台后台代码如下:
public class Test {
private static final String APPID = "";// 微信应用唯一标识 private static final String SECRET = ""; public void main(String code,String encryptedData,String iv) { JSONObject jsonObject = code2sessionKey(code); String openId = jsonObject.getString("openid");// 用户唯一标识 String session_key = jsonObject.getString("session_key");// 密钥 // 解密encryptedData,获取unionId相关信息 JSONObject json = decryptionUserInfo(encryptedData, session_key, iv); } /** * 发送请求用code换取sessionKey和相关信息 * * @param code * @return */ public static JSONObject code2sessionKey(String code) { String stringToken = String.format( "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", APPID, SECRET, code); String response = HttpUtils.httpsRequestToString(stringToken, "GET", null); return JSON.parseObject(response); } /** * 小程序解密用户数据 * * @param encryptedData * @param sessionKey * @param iv * @return */ public static JSONObject decryptionUserInfo(String encryptedData, String sessionKey, String iv) { // 被加密的数据 byte[] dataByte = Base64.decode(encryptedData); // 加密秘钥 byte[] keyByte = Base64.decode(sessionKey); // 偏移量 byte[] ivByte = Base64.decode(iv); try { // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 int base = 16; if (keyByte.length % base != 0) { int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyByte, 0, temp, 0, keyByte.length); keyByte = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); 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, "UTF-8"); return JSONObject.parseObject(result); } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 发送https请求 * * @param path * @param method * @param body * @return */ public static String httpsRequestToString(String path, String method, String body) { if (path == null || method == null) { return null; } String response = null; InputStream inputStream = null; InputStreamReader inputStreamReader = null; BufferedReader bufferedReader = null; HttpsURLConnection conn = null; try { // 创建SSLConrext对象,并使用我们指定的信任管理器初始化 SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); TrustManager[] tm = { new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } }; sslContext.init(null, tm, new java.security.SecureRandom()); // 从上面对象中得到SSLSocketFactory SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(path); conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(ssf); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); // 设置请求方式(get|post) conn.setRequestMethod(method); // 有数据提交时 if (null != body) { OutputStream outputStream = conn.getOutputStream(); outputStream.write(body.getBytes("UTF-8")); outputStream.close(); } // 将返回的输入流转换成字符串 inputStream = conn.getInputStream(); inputStreamReader = new InputStreamReader(inputStream, "UTF-8"); bufferedReader = new BufferedReader(inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } response = buffer.toString(); } catch (Exception e) { } finally { if (conn != null) { conn.disconnect(); } try { bufferedReader.close(); inputStreamReader.close(); inputStream.close(); } catch (IOException execption) { } } return response; }
}
与未授权情况下,多了一步解密数据包的动作,解密后就能获得我们需要的数据啦,所以在处理登录时一定要考虑好用户授权情况。附:encryptedData 解密后 json 结构
{
“openId”: “OPENID”,
“nickName”: “NICKNAME”,
“gender”: GENDER,
“city”: “CITY”,
“province”: “PROVINCE”,
“country”: “COUNTRY”,
“avatarUrl”: “AVATARURL”,
“unionId”: “UNIONID”,
“watermark”:
{
“appid”:“APPID”,
“timestamp”:TIMESTAMP
}
}(填坑…) 注意:上述返回的结果中如果还是没有unionId,这个时候需要检查是否完成开发者资质认证…
微信开放平台绑定小程序流程
前提:微信开放平台帐号必须已完成开发者资质认证
开发者资质认证流程:
登录微信开放平台(open.weixin.qq.com) – 帐号中心 – 开发者资质认证
img
绑定流程:
登录微信开放平台(open.weixin.qq.com)—管理中心—公众帐号—绑定公众帐号
img
-
java写微信小程序答辩问题_微信小程序java源代码研发注意哪些问题
2020-12-20 13:48:30java小程序代码1,通过ODBC连接import java.sql.*;public class ODBCTest {public static void main(String[] args) {Connection con = null;try {// 加载ODBC驱动(1) Class.forName("sun.jdbc.odbc.JdbcOdbcDriver")... -
微信小程序java开发流程分享
2017-06-05 08:54:51前段时间,我接触了微信的开发小程序,在开发过程中,我不得不承认微信小程序开发的简单粗暴,不多说,直接hight。 微信小程序可以去公众平台下载。有64位和32位的。在这里我就不多哔哔了。 下载完微信小程序后,... -
校园表白墙、微信表白墙、校园墙 微信小程序 JAVA 开发记录与分享
2019-01-11 13:10:46目录 最新版表白墙博客地址 ...1、微信小程序前台展示 2、功能介绍 3、后台管理 4、后端语言采用 JAVA 开发 5、体验此微信小程序 扫描下方二维码 6、如何联系我或需要源码进行联系 最新版表白墙博客地址 ... -
微信小程序java8 java7 java6 encryptedData 解密 异常处理
2018-07-19 17:17:00使用java8 java7 java6 解密微信小程序encryptedData可以回遇到一些错误 1.java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/PKCS7Padding 2.Java.security.... -
微信小程序java后台获取openid
2020-02-17 09:17:09分为小程序,开发者服务器(java端),微信接口服务(获取openid的接口) 小程序端: var that = this wx.login({ success: function (res) { var code = res.code;//发送给服务器的code if (code) { ... -
微信小程序java开发图片上传 ssm框架
2018-05-12 09:13:44微信小程序图片上传与pc端图片上传是不同的,话不多说直接上代码:(复制粘贴可用)微信小程序端:chooseImage(){ wx.chooseImage({ success: function (res) { var tempFilePaths = res.tempFilePaths wx.... -
微信小程序Java后台获取access_token存储数据库并定时更新
2018-11-14 14:53:43最近在学习小程序,做个笔记,希望和大家相互交流学习 小程序地图导航,显示天气源码 https://github.com/zzwwjjdj319/miniProgramAmap ... 微信小程序机票查询源码:https://gitee.com/sccqcd/ticket_i... -
微信小程序Java后台解密
2018-06-27 16:47:27前几天要做一个信息小程序获取用户的手机号码的功能,但是发现,拿到的数据都是加密的,官方并没有提供Java后台的源代码。。。找到了很久,看到这篇文章,学习了,然后在这基础上做了一些修改,emmm是一些修改。 ... -
微信小程序java后端开发记录(一):小程序后台设置
2019-09-09 15:37:18微信小程序开发相对没有微信公众号开发复杂,后台只需部分设置配置即可。 1.基本开发设置: 2.模板消息设置 小程序消息模板比公众号消息模板更为"死板",没有first头和remake备注参数,所以尽量选择最相近... -
微信小程序java后台秒杀等等微信支付等等
2018-07-24 16:44:27用javaSSM写的后台,前端有一些页面是在网上找了几个。小程序里面一切文字图片都是从后台里面上传,还可以二次开发。 此为上线小程序商城,...150元出售,带java后台,mysql数据,带经销存系统,小程序后台系统... -
微信小程序Java解密AES加密数据
2018-07-25 11:55:54微信demo下载下来发现没有Java版本,只能再找资料解密 我的Java解密代码是这样写的,可以用 import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java... -
微信小程序 java.net.ConnectException: Connection timed out: connect
2018-12-05 08:27:57微信小程序获取个人标识用如图的参数(https://img-ask.csdn.net/upload/201812/05/1543998324_564696.png) 利用下图的方法 之前不报错 今天突然报错![图片说明]...
-
多测师肖sir_高级金牌讲师_第2个月第10讲robotframework之定位(003)
-
【数据分析-随到随学】Spark理论及实战
-
文章里面的人
-
python基础知识:面向对象的实现与原理
-
linux好用的开发命令
-
海南大学《数据库原理与应用》期末试卷.pdf
-
如何利用市场情绪套利
-
TCP知识总结
-
pyechart数据可视化
-
外设抽象-按键抽象篇-未完成
-
转行做IT-第7章 数组
-
海南大学《TCP IP网络编程》复习习题.pdf
-
thinkphp5.1博客后台实战视频
-
花雨庭枪械起床材质包.zip
-
QT使用Q3DBars小部件实例.txt
-
【数据分析-随到随学】数据分析建模和预测
-
眼科治疗保护中心网页模板
-
海南大学网络安全基础练习题.pdf
-
海南大学《数据库原理》模拟题2及其答案.pdf
-
海南大学网络系统集成 复习内容.pdf