微信小程序获取openid、sessionKey及授权获取手机号码等信息

1.最近在开发小程序的项目中,服务端需要配合前端获取当前用户与微信绑定的手机号;需要以下两步:
1.1根据前端所传的code通过服务端调微信接口获取openId,sessionkey;
1.2根据前端所传的encrypdata,ivdata,sessionKey服务端进行解密后得到手机号

2.登录根绝凭证appId和appSecret校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程,然后后端通过code值调用微信的API地址   获取openId和sessionkey信息     然后前端页面通过点击授权按钮触(encrypdata、ivdata,sessionKey)调用后端接口进行解密获取授权用户信息

3.开发流程如下   首先在配置文件里面配置appId和appSecret   如下图:

4.获取微信openId sessionKey工具类   代码如下:

package com.longjin.wechat.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

/**
 * 请求微信小程序 api
 */
public class WeChatMiniClient {

    /**
     * 请求微信小程序api 获取 openId,session_key
     *
     * @param code      wx.login返回 code值
     * @param appId     小程序 appId
     * @param appSecret 小程序 appSecret
     * @return
     */
    public static JSONObject feighMini(String code, String appId, String appSecret) {
        //拼接url
        StringBuilder url = new StringBuilder("https://api.weixin.qq.com/sns/jscode2session?");
        url.append("appid=");//appId设置
        url.append(appId);
        url.append("&secret=");//secret设置
        url.append(appSecret);
        url.append("&js_code=");//code设置
        url.append(code);
        url.append("&grant_type=authorization_code"); //值固定
        JSONObject jsonObject = new JSONObject();
        try {
            HttpClient client = HttpClientBuilder.create().build();//构建一个Client
            HttpGet get = new HttpGet(url.toString());    //构建一个GET请求
            HttpResponse response = client.execute(get);//提交GET请求
            HttpEntity result = response.getEntity();//拿到返回的HttpResponse的"实体"
            String content = EntityUtils.toString(result);
            jsonObject = JSON.parseObject(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }
}

 

5.调用工具类获取到sessionkey和openid放入redis中   等前端点用户授权之后和encrypdata、ivdata一起传过来,注意这里不要直接把sessionkey直接放到sessionkey放到接口中返到前端,sessionkey属于私密信息  我这里是保存到redis中  代码如下:

public Map<String, Object> loginAuto(String code) throws Exception {
    Map<String, Object> map = new HashMap<>();
    //请求小程序api
    JSONObject jsonObject = WeChatMiniClient.feighMini(code, caseAppId, caseAppSecret);
    Map<String, Object> tempMap = AllJsonUtils.convertJson2Object(jsonObject, Map.class);
    //包含错误码
    if (tempMap.containsKey("errcode")) {
        String errCode = tempMap.get("errcode").toString();
        //错误 非法请求
        //系统返回msg,携带英文
        String sysMsg = tempMap.get("errmsg").toString();
        map.put("errorCode", errCode);
        map.put("errorMsg", MiniConstants.getMsg(errCode, sysMsg));
    } else if (tempMap.containsKey("session_key")) {
        //获取用户唯一标识
        String openId = tempMap.get("openid").toString();
        map.put("openId",openId);
            //将openId与sessionKey关联 放入缓存中
        redisUtil.setex(openId, tempMap.get("session_key").toString(), Contents.appRedisLoginTimeOut, Contents.userIndexdb);
    }
    return map;
}

 

6.点击授权获取手机号码  代码如下:

/**
     *  <desc>
     *      解密与微信绑定的手机号
     *  </desc>
     *
     * @param encrypdata 微信参数
     * @param ivdata 微信参数
     * @param sessionKey 会话密钥
     * @return
     * @createDate 2018/11/24
     */
    @RequestMapping(path = "/getPhoneNum",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO getPhoneNum(String encrypdata,String ivdata,String sessionKey){
        try {
            if(StringUtils.isEmpty(encrypdata) || StringUtils.isEmpty(ivdata) || StringUtils.isEmpty(sessionKey)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            byte[] encrypData = Base64.decode(encrypdata);
            byte[] ivData = Base64.decode(ivdata);
            byte[] sessionKeyByte = Base64.decode(sessionKey);
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(sessionKeyByte, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            //解析解密后的字符串 
            String phoneNum = new String(cipher.doFinal(encrypData),"UTF-8");

           JSONObject jsonObjects = JSONObject.parseObject(json); 

         String phoneNumber = jsonObjects.getString("phoneNumber");//用户手机号

            return  new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),phoneNum);
        }catch (Exception e){
            throw new DataAccessException("【小程序_注册登录版块】解密与微信绑定的手机号失败",e);
        }
    }

7.以上就是获取授权之后的用户手机号码    令附上项目中实际应用  代码如下:
 

@Override
public ResultsCode saveUserInfo(GlobalUser globalUser){
    try {
        String sessionKey = "";
             sessionKey = redisUtil.get(globalUser.getOpenId(), Contents.userIndexdb);
             //sessionKey查询不到查数据库
        if(StringUtils.isBlank(sessionKey)){
            VipThirdAccountUser vipThirdAccountUser = vipThirdAccountUserDao.findByAccountId(globalUser.getOpenId());
             sessionKey = vipThirdAccountUser.getAccountKey();
        }
        byte[] encrypData = com.sun.org.apache.xerces.internal.impl.dv.util.Base64.decode(globalUser.getEncryptedData());
        byte[] ivData = com.sun.org.apache.xerces.internal.impl.dv.util.Base64.decode(globalUser.getIv());
        byte[] sessionKeyByte = Base64.decode(sessionKey);
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(sessionKeyByte, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        //解析解密后的字符串
        String json = new String(cipher.doFinal(encrypData),"UTF-8");
        JSONObject jsonObjects = JSONObject.parseObject(json);
        String phoneNumber = jsonObjects.getString("phoneNumber");
        //通过openId查询
        VipThirdAccountUser vipThirdAccountUser = vipThirdAccountUserDao.findByAccountId(globalUser.getOpenId());
        Map<String,Object>   map = new HashMap<>();
        //没有对应数据 加入用户数据
        if (null == vipThirdAccountUser) {//新用户
            globalUser.setAccountId(globalUser.getOpenId());
            globalUser.setPhone(phoneNumber);
            globalUser.setAccountKey(sessionKey);
            addUserInfo(globalUser);
        } else {//老用户
            String username = vipThirdAccountUser.getUsername();
            GlobalUser byUserName = globalUserDao.findByUserName(username);
            if (null != byUserName) {
                doCommon(map, byUserName, globalUser.getOpenId());
               return ResultsCode.success(map);
            }
        }
    }catch (Exception e){
        return ResultsCode.Fail();
    }
    return ResultsCode.success();
}


/**
 * 设置公共部分
 */
public void doCommon(Map<String, Object> map,  GlobalUser globalUser, String openId) {
    //判断是否存在对应key
    boolean loginExist = redisUtil.exists(SysStringUtils.md5(globalUser.getUsername() + "mini"), Contents.userIndexdb);
    if (loginExist) {
        String oldToken = redisUtil.get(SysStringUtils.md5(globalUser.getUsername() + "mini"), Contents.userIndexdb);
        redisUtil.del(Contents.userIndexdb, oldToken);
    }
    GlobalUserExt globalUserExt = globalUserExtDao.findByUserId(globalUser.getUserId().toString());
    globalUser.setNickname(globalUserExt.getNickname());
    globalUser.setImagePath(globalUserExt.getImagePath());
    globalUser.setWeixinId(globalUserExt.getWeixinId());
    map.put("globalUser", globalUser);
    String token = TokenUtils.getToken(globalUser.getUserId().toString(), globalUser.getUsername(), SysStringUtils.md5(globalUser.getUsername() + "caseMini"), globalUser.getUserId().toString());
    map.put("token", token);
    map.put("openId", openId);
    //将生成的token存入Redis中
    redisUtil.setex(token, token, Contents.appRedisLoginTimeOut, Contents.userIndexdb);
    redisUtil.setex(SysStringUtils.md5(globalUser.getUsername() + "mini"), token, Contents.appRedisLoginTimeOut, Contents.userIndexdb);
    AdminRole role  = new AdminRole();
    role.setUserId(globalUser.getUserId());
    List<AdminRole> roleList = roleManageService.getRoleList(role);
    map.put("roleList", roleList);
    //获取角色全部菜单资源列表
    List<AdminMenu>   adminMenuList = new ArrayList<>();
    if (null != roleList && roleList.size() != 0) {
        for (AdminRole r : roleList) {
            List<AdminMenu> roleMenuList = roleManageService.getRoleMenuList(r.getRoleId());
            adminMenuList.addAll(roleMenuList);
        }
    }
    map.put("adminMenuList",adminMenuList);
    String uid = globalUser.getUserId().toString();
    new Thread() {
        @Override
        public void run() {
            if (StringUtils.isNotBlank(uid)) {
                globalUserDao.updateStatus(uid);
            }
        }
    }.start();
}


/**
 * 添加用户信息
 *
 * @param globalUser
 */
public  void addUserInfo(GlobalUser globalUser){
    //用户统一信息添加
    String userId = StringStrUtils.getUUID();
    globalUser.setSource(NumberEnum.FIRST.code());
    globalUser.setMobile(globalUser.getPhone());
    globalUser.setUsername(globalUser.getPhone());
    globalUser.setCreateType(NumberEnum.SECOND.code());
    globalUser.setUserId(userId);
     globalUserDao.save(globalUser);
    //会员用户添加
    VipMemberUser vipMemberUser  = new VipMemberUser();
    vipMemberUser.setUserId(userId);
    Integer memberId = vipMemberUserDao.save(vipMemberUser);
    //三方授权登录添加
    VipThirdAccountUser vipThirdAccountUser = new VipThirdAccountUser();
    vipThirdAccountUser.setMemberId(memberId);
    vipThirdAccountUser.setSource(globalUser.getThirdAccountSource());
    vipThirdAccountUser.setAccountId(globalUser.getAccountId());
    vipThirdAccountUser.setAccountKey(globalUser.getAccountKey());
    vipThirdAccountUser.setUserId(userId);
    vipThirdAccountUser.setUsername(globalUser.getPhone());
    vipThirdAccountUserDao.save(vipThirdAccountUser);
    AdminRole role  = new AdminRole();
    role.setAppId("PA-PLATFORM-XH");
    role.setRoletypeId("R32");
    role.setName("市民");
    role.setCode("CITIZEN");
    role.setPriority(NumberEnum.FIVE.code());
    role.setIsRegular(NumberEnum.FIRST.code());
    role.setIsSuper(NumberEnum.ZERO.code());
    role.setIsPublic(NumberEnum.ZERO.code());
    role.setStatus(NumberEnum.FIRST.code());
    role.setDescription("市民");
    role.setUserId(userId);
    Integer roleId = roleManageService.add(role);

    //会员用户组
   SasMemberGroup sasMemberGroup = new SasMemberGroup();
    sasMemberGroup.setRoleId(roleId);
    sasMemberGroup.setName("市民");
    sasMemberGroup.setCode("CITIZEN");
    sasMemberGroup.setIsCommonGroup(NumberEnum.FIRST.code());
    sasMemberGroup.setIsLeaderGroup(NumberEnum.ZERO.code());
    sasMemberGroup.setIsGridGroup(NumberEnum.ZERO.code());
    sasMemberGroup.setIsPartyGroup(NumberEnum.ZERO.code());
    sasMemberGroup.setIsWorkGroup(NumberEnum.ZERO.code());
    sasMemberGroup.setIsVillageGroup(NumberEnum.ZERO.code());
    sasMemberGroup.setIsDisabled(NumberEnum.ZERO.code());
    sasMemberGroup.setPriority(NumberEnum.FIRST.code());
    sasMemberGroup.setDescription("市民");
    Integer groupId = sasMemberGroupDao.add(sasMemberGroup);

    //添加用户组关联
    SasMemberGroupUser sasMemberGroupUser = new SasMemberGroupUser();
    sasMemberGroupUser.setGroupId(groupId);
    sasMemberGroupUser.setMemberId(memberId);
    sasMemberGroupUserDao.add(sasMemberGroupUser);

    //添加用户基本信息
    GlobalUserExt globalUserExt = new GlobalUserExt();
    globalUserExt.setUserId(userId);
    globalUserExt.setNickname(globalUser.getNickname());
    globalUserExt.setWeixinId(globalUser.getWeixinId());
    globalUserExt.setImagePath(globalUser.getImagePath());
    globalUserExtDao.save(globalUserExt);
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值