微信小程序> 微信web开发,微信小程序与微信网页开发

微信web开发,微信小程序与微信网页开发

浏览量:1035 时间: 来源:qq_42342242
微信web开发只需要code值,但是小程序需要一个code值,一个encryptData,一个iv
首先先看图

箭头部分为微信给我们的,就是前端需要传过来的。
步骤为:
小程序客户端调用wx.login,回调里面包含js_code。然后将js_code发送到服务器A(开发者服务器),服务器A向微信服务器发起请求附带js_code、appId、secretkey和grant_type参数,以换取用户的openid和session_key(会话密钥)。服务器A拿到session_key后,生成一个随机数我们叫3rd_session,以3rdSessionId为key,以session_key+openid为value缓存到redis或memcached中;因为微信团队不建议直接将session_key在网络上传输,由开发者自行生成唯一键与session_key关联。其作用是:将3rdSessionId返回给客户端,维护小程序登录态。通过3rdSessionId找到用户session_key和openid。客户端拿到3rdSessionId后缓存到storage,通过wx.getUserIinfo可以获取到用户敏感数据encryptedData。客户端将encryptedData、3rdSessionId和偏移量一起发送到服务器A服务器A根据3rdSessionId从缓存中获取session_key在服务器A使用AES解密encryptedData,从而实现用户敏感数据解密
重点在6、7、8三个环节。AES解密三个参数:
密文encryptedData密钥aesKey偏移向量iv概念性的东西就这些,下面看代码
首先前端需要传给我们的东西就是三个一个code值,一个encryptData,一个iv,
先写方法
packagecom.everest.academy.util;importcom.alibaba.fastjson.JSON;importcom.alibaba.fastjson.JSONObject;importlombok.extern.slf4j.Slf4j;importorg.bouncycastle.jce.provider.BouncyCastleProvider;importorg.bouncycastle.util.encoders.Base64;importjavax.crypto.Cipher;importjavax.crypto.spec.IvParameterSpec;importjavax.crypto.spec.SecretKeySpec;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.PrintWriter;importjava.net.URL;importjava.net.URLConnection;importjava.security.AlgorithmParameters;importjava.security.Security;importjava.util.Arrays;importjava.util.HashMap;importjava.util.Iterator;importjava.util.Map;/@ClassNameXcxUtils@Description微信小程序方法@Author田野@Data22:14@Version1.0/@Slf4jpublicclassXcxUtils{/获取微信小程序session_key和openid@authorzhy@paramcode调用微信登陆返回的Code@return/publicstaticJSONObjectgetSessionKeyOropenid(Stringcode,Stringappid,Stringsecret){StringrequestUrl="https://api.weixin.qq.com/sns/jscode2session";//请求地址MapString,StringrequestUrlParam=newHashMapString,String();requestUrlParam.put("appid",appid);//开发者设置中的appIdrequestUrlParam.put("secret",secret);//开发者设置中的appSecretrequestUrlParam.put("js_code",code);//小程序调用wx.login返回的coderequestUrlParam.put("grant_type","authorization_code");//默认参数//发送post请求读取调用微信https://api.weixin.qq.com/sns/jscode2session//接口获取openid用户唯一标识JSONObjectjsonObject=JSON.parseObject(sendPost(requestUrl,requestUrlParam));System.out.println(jsonObject);returnjsonObject;}/解密用户敏感数据获取用户信息@authorzhy@paramsessionKey数据进行加密签名的密钥@paramencryptedData包括敏感数据在内的完整用户信息的加密数据@paramiv加密算法的初始向量@return/publicstaticJSONObjectgetUserInfo(StringencryptedData,StringsessionKey,Stringiv){encryptedData=encryptedData.replace("","+");sessionKey=sessionKey.replace("","+");iv=iv.replace("","+");//被加密的数据byte[]dataByte=Base64.decode(encryptedData);//加密秘钥byte[]keyByte=Base64.decode(sessionKey);//偏移量byte[]ivByte=Base64.decode(iv);try{//如果密钥不足16位,那么就补足.这个if中的内容很重要intbase=16;if(keyByte.length%base!=0){intgroups=keyByte.length/base+(keyByte.length%base!=0?1:0);byte[]temp=newbyte[groupsbase];Arrays.fill(temp,(byte)0);System.arraycopy(keyByte,0,temp,0,keyByte.length);keyByte=temp;}//初始化Security.addProvider(newBouncyCastleProvider());Ciphercipher=Cipher.getInstance("AES/CBC/PKCS7Padding","BC");SecretKeySpecspec=newSecretKeySpec(keyByte,"AES");AlgorithmParametersparameters=AlgorithmParameters.getInstance("AES");parameters.init(newIvParameterSpec(ivByte));cipher.init(Cipher.DECRYPT_MODE,spec,parameters);//初始化byte[]resultByte=cipher.doFinal(dataByte);if(null!=resultByte&&resultByte.length0){Stringresult=newString(resultByte,"UTF-8");returnJSON.parseObject(result);}}catch(Exceptione){log.error(e.getMessage(),e);}returnnull;}/向指定URL发送POST方法的请求@paramurl发送请求的URL@param@return所代表远程资源的响应结果/publicstaticStringsendPost(Stringurl,MapString,?paramMap){PrintWriterout=null;BufferedReaderin=null;Stringresult="";Stringparam="";IteratorStringit=paramMap.keySet().iterator();while(it.hasNext()){Stringkey=it.next();param+=key+"="+paramMap.get(key)+"&";}try{URLrealUrl=newURL(url);//打开和URL之间的连接URLConnectionconn=realUrl.openConnection();//设置通用的请求属性conn.setRequestProperty("accept","/");conn.setRequestProperty("connection","Keep-Alive");conn.setRequestProperty("Accept-Charset","utf-8");conn.setRequestProperty("user-agent","Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)");//发送POST请求必须设置如下两行conn.setDoOutput(true);conn.setDoInput(true);//获取URLConnection对象对应的输出流out=newPrintWriter(conn.getOutputStream());//发送请求参数out.print(param);//flush输出流的缓冲out.flush();//定义BufferedReader输入流来读取URL的响应in=newBufferedReader(newInputStreamReader(conn.getInputStream(),"UTF-8"));Stringline;while((line=in.readLine())!=null){result+=line;}}catch(Exceptione){log.error(e.getMessage(),e);}//使用finally块来关闭输出流、输入流finally{try{if(out!=null){out.close();}if(in!=null){in.close();}}catch(IOExceptionex){ex.printStackTrace();}}returnresult;}}注解写的很明白的,应该没什么看不懂。
之后就是service层
packagecom.everest.academy.service.impl;importcom.alibaba.fastjson.JSONObject;importcom.everest.academy.business.dto.LoginUserDTO;importcom.everest.academy.business.dto.WechatTokenDto;importcom.everest.academy.framework.exception.ResourceIsNullException;importcom.everest.academy.framework.pojo.User;importcom.everest.academy.persistence.mapper.UserMapper;importcom.everest.academy.service.WechatService;importcom.everest.academy.util.WechatUtil;importcom.everest.academy.util.XcxUtils;importlombok.extern.slf4j.Slf4j;importorg.apache.commons.lang.StringUtils;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importjava.util.Date;/@ClassNameWechatServiceImpl@Description微信sgervice@Author田野@Data20:25@Version1.0/@Slf4j@ServicepublicclassWechatServiceImplimplementsWechatService{@AutowiredUserMapperuserMapper;@OverridepublicLoginUserDTOgetUserByCode(Stringcode,StringencryptedData,Stringiv)throwsException{log.info("传进来的值"+encryptedData+"另一个"+iv);JSONObjectshopAddress=null;if(StringUtils.isNotEmpty(code)){Stringappid="填自己的";Stringsecret="填自己的";shopAddress=XcxUtils.getSessionKeyOropenid(code,appid,secret);}assertshopAddress!=null;StringopenId=shopAddress.getString("openid");StringsessionKey=shopAddress.getString("session_key");log.info("session_key为:"+sessionKey);JSONObjectuser1=XcxUtils.getUserInfo(encryptedData,sessionKey,iv);//user这里根据用户openId查询是否有这个用户。Useruser=userMapper.findByOpenId(openId);LoginUserDTOloginUserDTO=newLoginUserDTO();if(user!=null){log.info("用户的状态"+user.getState());if(user.getState()==1){//有的话,直接就进入,直接将信息返回给前端loginUserDTO.setId(user.getId());loginUserDTO.setOpenId(openId);returnloginUserDTO;}thrownewException("无法登录,账号被冻结");}//没有的话,创建该学生的信息,然后再传给部分数据给前端UsernewUser=newUser();newUser.setOpenId(openId);assertuser1!=null;newUser.setAddress(user1.getString("city"));newUser.setHeadImgUrl(user1.getString("avatarUrl"));newUser.setName(user1.getString("nickName"));newUser.setState(1);newUser.setBeans(0);newUser.setBinding(0);newUser.setCreate_at(newDate().getTime());newUser.setCreate_by("系统创建");userMapper.insert(newUser);Useruser2=userMapper.findByOpenId(openId);LoginUserDTOloginUserDTO1=newLoginUserDTO();loginUserDTO1.setId(user2.getId());log.info("id的值"+newUser.getId());loginUserDTO1.setOpenId(newUser.getOpenId());loginUserDTO1.setBinding(newUser.getState());returnloginUserDTO1;}}也写的挺清楚的,通过openId判断是否有这个用户
controller
packagecom.everest.academy.controller;importcom.everest.academy.business.vo.ResponseVo;importcom.everest.academy.framework.exception.ResourceIsNullException;importcom.everest.academy.service.WechatService;importcom.everest.academy.util.ResultUtil;importio.swagger.annotations.Api;importio.swagger.annotations.ApiImplicitParam;importio.swagger.annotations.ApiImplicitParams;importio.swagger.annotations.ApiOperation;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.validation.annotation.Validated;importorg.springframework.web.bind.annotation.;importjava.util.Map;/@ClassNameWechatController@Description微信登录验证@Author田野@Data15:56@Version1.0/@Slf4j@Api(tags="WechatController",description="微信开发API")@RestController@RequestMapping("/a/home")@ValidatedpublicclassWechatController{@AutowiredWechatServicewechatService;@ApiOperation(value="微信登录验证",notes="通过获取的codeId值登录")@PostMapping("/{code}")publicResponseVoWechatLogin(@PathVariable("code")Stringcode,@RequestParam("encryptedData")StringencryptedData,@RequestParam("iv")Stringiv)throwsException{log.info("传进来的未"+encryptedData+"iv为"+iv);returnResultUtil.success("微信登录成功",wechatService.getUserByCode(code,encryptedData,iv));}}就有一点问题
测试的时候,每次传参都读不到+号,每次都把我的+号弄掉。

所以这里运用了一个replace,完美解决
微信网页开发,通过codeId得到access_token,通过access_token和openid获取用户基本信息
packagecom.everest.academy.util;importcom.everest.academy.business.dto.LoginUserDTO;importcom.everest.academy.business.dto.WechatTokenDto;importcom.google.gson.Gson;importcom.google.gson.JsonObject;importlombok.extern.slf4j.Slf4j;importorg.apache.http.HttpEntity;importorg.apache.http.HttpResponse;importorg.apache.http.client.methods.HttpGet;importorg.apache.http.impl.client.CloseableHttpClient;importorg.apache.http.impl.client.HttpClients;importorg.apache.http.util.EntityUtils;importjava.util.HashMap;importjava.util.Map;/@ClassNameWechatUtil@DescriptionTODO@Author田野@Data19:25@Version1.0/@Slf4jpublicclassWechatUtil{publicfinalstaticStringAPPID="自己的";publicfinalstaticStringAPPSECRET="自己的";/获取请求用户信息的access_token@paramcode@return/publicstaticWechatTokenDtogetUserInfoAccessToken(Stringcode){JsonObjectobject=null;WechatTokenDtowechatTokenDto=newWechatTokenDto();MapString,Stringdata=newHashMap();try{Stringurl=String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",APPID,APPSECRET,code);log.info("requestaccessTokenfromurl:{}",url);CloseableHttpClienthttpClient=HttpClients.createDefault();HttpGethttpGet=newHttpGet(url);HttpResponsehttpResponse=httpClient.execute(httpGet);HttpEntityhttpEntity=httpResponse.getEntity();Stringtokens=EntityUtils.toString(httpEntity,"utf-8");Gsontoken_gson=newGson();object=token_gson.fromJson(tokens,JsonObject.class);log.info("requestaccessTokensuccess.[result={}]",object);wechatTokenDto.setOpenid(object.get("openid").toString().replaceAll(""",""));wechatTokenDto.setAccess_token(object.get("access_token").toString().replaceAll(""",""));wechatTokenDto.setRefresh_token(object.get("refresh_token").toString().replaceAll(""",""));wechatTokenDto.setScope(object.get("scope").toString().replaceAll(""",""));wechatTokenDto.setExpires_in(Integer.parseInt(object.get("expires_in").toString().replaceAll(""","")));//data.put("openid",object.get("openid").toString().replaceAll(""",""));//data.put("access_token",object.get("access_token").toString().replaceAll(""",""));//data.put("expires_in",object.get("expires_in").toString().replaceAll(""",""));//data.put("refresh_token",object.get("refresh_token").toString().replaceAll(""",""));//data.put("scope",object.get("scope").toString().replaceAll(""",""));}catch(Exceptionex){log.error("failtorequestwechataccesstoken.[error={}]",ex);}returnwechatTokenDto;}/通过access_token和openid获取用户基本信息@paramaccessToken@paramopenId@return/publicstaticLoginUserDTOgetUserInfo(StringaccessToken,StringopenId){LoginUserDTOloginUserDTO=newLoginUserDTO();Stringurl="https://api.weixin.qq.com/sns/userinfo?access_token="+accessToken+"&openid="+openId+"&lang=zh_CN";log.info("requestuserinfofromurl:{}",url);JsonObjectuserInfo=null;try{CloseableHttpClienthttpClient=HttpClients.createDefault();HttpGethttpGet=newHttpGet(url);HttpResponsehttpResponse=httpClient.execute(httpGet);HttpEntityhttpEntity=httpResponse.getEntity();Stringresponse=EntityUtils.toString(httpEntity,"utf-8");Gsontoken_gson=newGson();userInfo=token_gson.fromJson(response,JsonObject.class);log.info("getuserinfosuccess.[result={}]",userInfo);loginUserDTO.setOpenId(userInfo.get("openid").toString().replaceAll(""",""));loginUserDTO.setCountry(userInfo.get("country").toString().replaceAll(""",""));loginUserDTO.setProvince(userInfo.get("province").toString().replaceAll(""",""));loginUserDTO.setCity(userInfo.get("city").toString().replaceAll(""",""));loginUserDTO.setHeadImgUrl(userInfo.get("headimgurl").toString().replaceAll(""",""));loginUserDTO.setSex(Integer.valueOf(userInfo.get("sex").toString().replaceAll(""","")));loginUserDTO.setNickname(userInfo.get("nickname").toString().replaceAll(""",""));//data.put("openid",userInfo.get("openid").toString().replaceAll(""",""));//data.put("nickname",userInfo.get("nickname").toString().replaceAll(""",""));//data.put("city",userInfo.get("city").toString().replaceAll(""",""));//data.put("province",userInfo.get("province").toString().replaceAll(""",""));//data.put("country",userInfo.get("country").toString().replaceAll(""",""));//data.put("headimgurl",userInfo.get("headimgurl").toString().replaceAll(""",""));}catch(Exceptionex){log.error("failtorequestwechatuserinfo.[error={}]",ex);}returnloginUserDTO;}}@OverridepublicLoginUserDTOwechat(Stringcode)throwsResourceIsNullException{//调用封装的微信方法,通过code值得到wechatTokenDtoWechatTokenDtowechatTokenDto=WechatUtil.getUserInfoAccessToken(code);StringaccessToken=wechatTokenDto.getAccess_token();//得到accessTokenStringopenId=wechatTokenDto.getOpenid();//得到openId//user这里根据用户openId查询是否有这个用户。Useruser=userMapper.findByOpenId(openId);LoginUserDTOloginUserDTO=WechatUtil.getUserInfo(accessToken,openId);log.info("用户信息"+user);if(user!=null){//有的话,直接就进入,直接将信息返回给前端//loginUserDTO.setOpenId(openId);loginUserDTO.setId(user.getId());loginUserDTO.setBinding(user.getState());returnloginUserDTO;}else{//没有的话,创建该学生的信息,然后再传给部分数据给前端UsernewUser=newUser();newUser.setOpenId(loginUserDTO.getOpenId());newUser.setAddress(loginUserDTO.getCity());newUser.setHeadImgUrl(loginUserDTO.getHeadImgUrl());newUser.setName(loginUserDTO.getNickname());log.info("用户昵称"+loginUserDTO.getNickname());newUser.setState(1);newUser.setBeans(0);newUser.setBinding(0);newUser.setCreate_at(newDate().getTime());newUser.setCreate_by("系统创建");userMapper.insert(newUser);LoginUserDTOloginUserDTO1=newLoginUserDTO();loginUserDTO1.setId(newUser.getId());log.info("id的值"+newUser.getId());loginUserDTO1.setOpenId(newUser.getOpenId());loginUserDTO1.setBinding(newUser.getState());returnloginUserDTO1;}}基本就是这个样子,后续看下能不能写的更加详细。

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎