前段時間,微信更改了授權方式,采用用戶主動式授權,也就是可授權多次,並不像之前的取消就不彈了
下面代碼效果:檢測是否授權,未授權時出現授權按鈕,已授權則直接顯示用戶信息,方式使用了緩存,有更好的方案請在評論區回復一下,(文中appid,appsecret均為測試小程序)
index.js
Page({ data: { hasUserInfo: false, canIUseGetUserProfile: false, }, onLoad() { /* 從緩存中取出去數據 */ let userInfo = wx.getStorageSync('userInfo'); let wxInfos = wx.getStorageSync('wxInfos'); if (0 == Object.keys(userInfo).length) { this.setData({canIUseGetUserProfile: true}) wx.login({success:(rs) => {wx.setStorageSync("code",rs.code); } }); }else{ this.setData({ hasUserInfo:true, userInfo:userInfo, wxInfos:wxInfos }) } }, getUserProfile(e) { wx.getUserProfile({ desc: '授權', success: (wrs) => { var code = wx.getStorageSync("code") if(code){ let dataJson = { appId: app.globalData.appId, code : code, iv : wrs.iv, encryptedData : wrs.encryptedData } /* 發起用戶微信開放信息請求 */ request.requestPost(true, app, '/xxx', dataJson, data =>{ if(data.stateCode=="0"){ var result = JSON.parse(data.result); _self.setData({ hasUserInfo: true, userInfo:result, wxInfos:JSON.parse(result.wxInfos) }) /* 使用緩存記錄信息 */ wx.setStorageSync('userInfo', result); wx.setStorageSync('wxInfos', JSON.parse(result.wxInfos)); }else { console.log(data) } }); } },fail:()=>{ console.log("用戶拒絕授權"); } }); } })
index.wxml
<view class="container"> <view class="userinfo"> <block wx:if="{{!hasUserInfo}}"> <button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 獲取頭像昵稱 </button> </block> <block wx:else> <image bindtap="bindViewTap" class="userinfo-avatar" src="{{wxInfos.avatarUrl}}" mode="cover"></image> <text class="userinfo-nickname">{{wxInfos.nickName}}</text> <text class="userinfo-nickname">openId=> {{userInfo.openid}}</text> <text class="userinfo-nickname">unionId=> {{userInfo.unionid}}</text> </block> </view> </view>
后台:
GetWxInfoServlet.java
import org.apache.commons.lang.StringUtils; import com.alibaba.fastjson.JSONObject; import com.src.minback.utils.HttpRequest; import com.src.minback.utils.WxAesUtil; /** * 模擬獲取微信用戶信息及微信小程序版本信息 * * @author liuwl */ public class GetWxInfoServlet extends HttpServlet { private static final long serialVersionUID = 1L; static String wxspAppid = "wxfc5a797bc1295c71"; static String wxspSecret = "47067172d687958df709f9396b83e3ed"; static String grant_type = "authorization_code"; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 設置字符集 req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); // 獲取輸出 PrintWriter out = resp.getWriter(); JSONObject jsonObj = new JSONObject(); JSONObject result = new JSONObject(); System.out.println("wx.login 返回的code:" + req.getParameter("code")); String code = req.getParameter("code"); // 登錄憑證不能為空 if (code != null && code.length() > 0) { // 請求參數 String params = "appid=" + wxspAppid + "&secret=" + wxspSecret + "&js_code=" + code + "&grant_type=" + grant_type; // 發送請求 String sr = HttpRequest.sendGet("https://api.weixin.qq.com/sns/jscode2session", params); // 解析相應內容(轉換成json對象) JSONObject json = JSONObject.parseObject(sr); // 獲取會話密鑰(session_key) String session_key = json.get("session_key").toString(); System.out.println("session_key:" + session_key); // 用戶的唯一標識(openid) String openid = (String) json.get("openid"); System.out.println("openid:" + openid); result.put("openid", openid); // 開放平台的唯一標識符(unionid) String unionid = (String) json.get("unionid"); System.out.println("unionid:" + unionid); result.put("unionid", unionid); if (StringUtils.isNotEmpty(openid)) { jsonObj.put("stateCode", "0"); jsonObj.put("stateDesc", "操作成功"); // 解密encryptedData try { String encryptedData = req.getParameter("encryptedData"); String iv = req.getParameter("iv"); System.out.println("iv:" + iv); System.out.println("encryptedData:" + encryptedData); JSONObject decryptData = WxAesUtil.decrypt(encryptedData, session_key, iv, "UTF-8"); System.out.println("-->" + decryptData); if (decryptData!=null) { result.put("wxInfos", decryptData.toString()); } jsonObj.put("result", result.toJSONString()); } catch (Exception e) { e.printStackTrace(); } } else { jsonObj.put("stateCode", "1"); jsonObj.put("stateDesc", "獲取失敗"); } } else { jsonObj.put("stateCode", "3"); jsonObj.put("stateDesc", "code為空"); } System.out.println("僅獲取微信用戶所有信息(userData):" + jsonObj); out.print(jsonObj); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
工具類:WxAesUtil.java
import org.apache.commons.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; import com.alibaba.fastjson.JSONObject; 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; import java.util.Arrays; public class WxAesUtil { static { //BouncyCastle是一個開源的加解密解決方案,主頁在http://www.bouncycastle.org/ Security.addProvider(new BouncyCastleProvider()); } /** * AES解密 * * @param data //密文,被加密的數據 * @param key //秘鑰 * @param iv //偏移量 * @param encodingFormat //解密后的結果需要進行的編碼 * @return * @throws Exception */ public static JSONObject decrypt(String data, String key, String iv, String encodingFormat) throws Exception { //被加密的數據 byte[] dataByte = Base64.decodeBase64(data); //加密秘鑰 byte[] keyByte = Base64.decodeBase64(key); //偏移量 byte[] ivByte = Base64.decodeBase64(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; } 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); } return null; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidParameterSpecException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } }
效果: