需求说明:

用户通过小程序登录,进入到平台系统,进行各功能操作;

解决方案:

首先通过对接小程序,用户通过小程序登录及授权获取用户信息,后端调用接口获取微信用户信息,进行保存到数据库,然后返回token给前端(实际在这里相当于用户的一个注册及登录),前端使用该token访问所有接口;

相关代码:

首先我们需要用到 http工具类 方便后续的接口调用:import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;public class HttpClientUtils {final static int TIMEOUT = 1000;final static int TIMEOUT_MSEC = 5 * 1000;   public static String doPost(String url, Map<String, String> paramMap) throws IOException {// 创建Httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = null;String resultString = "";try {// 创建Http Post请求HttpPost httpPost = new HttpPost(url);// 创建参数列表if (paramMap != null) {List<NameValuePair> paramList = new ArrayList<>();for (Map.Entry<String, String> param : paramMap.entrySet()) {paramList.add(new BasicNameValuePair(param.getKey(), param.getValue()));}// 模拟表单UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);httpPost.setEntity(entity);}httpPost.setConfig(builderRequestConfig());// 执行http请求response = httpClient.execute(httpPost);resultString = EntityUtils.toString(response.getEntity(), "UTF-8");} catch (Exception e) {throw e;} finally {try {response.close();} catch (IOException e) {throw e;}}return resultString;}private static RequestConfig builderRequestConfig() {return RequestConfig.custom().setConnectTimeout(TIMEOUT_MSEC).setConnectionRequestTimeout(TIMEOUT_MSEC).setSocketTimeout(TIMEOUT_MSEC).build();}
}
小程序用户表
CREATE TABLE `wechat_user` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`nickname` varchar(100) DEFAULT NULL COMMENT '用户昵称',`avatar_url` varchar(500) DEFAULT NULL COMMENT '用户头像',`gender` int(11) DEFAULT NULL COMMENT '性别  0-未知、1-男性、2-女性',`country` varchar(100) DEFAULT NULL COMMENT '所在国家',`province` varchar(100) DEFAULT NULL COMMENT '省份',`city` varchar(100) DEFAULT NULL COMMENT '城市',`mobile` varchar(100) DEFAULT NULL COMMENT '手机号码',`open_id` varchar(100) NOT NULL COMMENT '小程序openId',`union_id` varchar(100) DEFAULT '' COMMENT '小程序unionId',`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '插入时间',`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`),KEY `idx_open_id` (`open_id`),KEY `idx_union_id` (`union_id`),KEY `idx_mobile` (`mobile`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='小程序用户表';

dto

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import javax.validation.constraints.NotNull;@Data
public class WechatLoginRequest {//登录时获取的 code,可通过wx.login获取@NotNull(message = "code不能为空")@ApiModelProperty(value = "微信code", required = true)private String code;//这个入参其实里面包含了用户的信息 下面的impl层 就是解析这个json获取用户信息@ApiModelProperty(value = "用户非敏感字段")private String rawData;@ApiModelProperty(value = "签名")private String signature;@ApiModelProperty(value = "用户敏感字段")private String encryptedData;@ApiModelProperty(value = "解密向量")private String iv;
}

主要代码:

controller


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
@RequestMapping("/wechat")
@Api(tags = {"微信小程序"}, value = "/wechat")
@Slf4j
public class LoginController {@Resourceprivate WechatService wechatService;@ApiOperation(value = "登入接口", httpMethod = "POST")@PostMapping("/login")public ResponseResult login(@Validated @RequestBody WechatLoginRequest loginRequest) throws Exception {return wechatService.getUserInfoMap(loginRequest);}
}

mapper

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mmc.aircraftsystemserver.api.wechet.pojo.WechatUser;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface WechatMapper extends BaseMapper<WechatUser> {}

impl

package com.mmc.aircraftsystemserver.api.wechet.service.impl;import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;@Slf4j
@Service
public class WechatServiceImpl extends ServiceImpl<WechatMapper, WechatUser> implements WechatService {//小程序 appId@Value("${wechat.appid}")private String APPID;//小程序 appSecret@Value("${wechat.secret}")private String SECRET;//${wechat.grantType} = authorization_code@Value("${wechat.grantType}")private String GRANT_TYPE;// ${wechat.url} = https://api.weixin.qq.com/sns/jscode2session@Value("${wechat.url}")private String REQUEST_URL;public ResponseResult getUserInfoMap(WechatLoginRequest loginRequest) throws Exception {JSONObject sessionKeyOpenId = getSessionKeyOrOpenId(loginRequest.getCode());// 获取openId && sessionKeyString openId = sessionKeyOpenId.getString("openid");String sessionKey = sessionKeyOpenId.getString("session_key");//校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)String signature2 = DigestUtils.sha1Hex(loginRequest.getRawData() + sessionKey);if (!loginRequest.getSignature().equals(signature2)) {return ResponseResult.errorResult(HttpCodeEnum.FAIL, "签名校验失败");}WechatUser insertOrUpdateDO = buildWechatUserAuthInfoDO(loginRequest, sessionKey, openId);// 根据code保存openId和sessionKeyJSONObject sessionObj = new JSONObject();sessionObj.put("openId", openId);sessionObj.put("sessionKey", sessionKey);// 根据openid查询用户QueryWrapper wrapper = new QueryWrapper();wrapper.eq("open_id",openId);WechatUser user = getOne(wrapper);if (user == null) {// 用户不存在,insert用户save(insertOrUpdateDO);} else {// 已存在,更新用户的信息UpdateWrapper<WechatUser> updateWrapper = new UpdateWrapper();updateWrapper.eq("openId",openId).set("nickname",insertOrUpdateDO.getNickname()).set("avatar_url",insertOrUpdateDO.getAvatarUrl()).set("gender",insertOrUpdateDO.getGender()).set("country",insertOrUpdateDO.getCountry()).set("province",insertOrUpdateDO.getProvince()).set("city",insertOrUpdateDO.getCity()).set("mobile",insertOrUpdateDO.getMobile());update(updateWrapper);}ResponseResult token = createToken(insertOrUpdateDO);return ResponseResult.okResult(token);}//调用接口private JSONObject getSessionKeyOrOpenId(String code) throws Exception {Map<String, String> requestUrlParam = new HashMap<>();requestUrlParam.put("appid", APPID);requestUrlParam.put("secret", SECRET);requestUrlParam.put("js_code", code);requestUrlParam.put("grant_type", GRANT_TYPE);// 发送post请求读取调用微信接口获取openid用户唯一标识String result = HttpClientUtils.doPost(REQUEST_URL, requestUrlParam);return JSON.parseObject(result);}private WechatUser buildWechatUserAuthInfoDO(WechatLoginRequest loginRequest, String sessionKey, String openId){WechatUser wechatUserDO = new WechatUser();wechatUserDO.setOpenId(openId);if (loginRequest.getRawData() != null) {RawDataDO rawDataDO = JSON.parseObject(loginRequest.getRawData(), RawDataDO.class);wechatUserDO.setNickname(rawDataDO.getNickName());wechatUserDO.setAvatarUrl(rawDataDO.getAvatarUrl());wechatUserDO.setGender(rawDataDO.getGender());wechatUserDO.setCity(rawDataDO.getCity());wechatUserDO.setCountry(rawDataDO.getCountry());wechatUserDO.setProvince(rawDataDO.getProvince());}// 解密加密信息,获取unionIDif (loginRequest.getEncryptedData() != null){JSONObject encryptedData = getEncryptedData(loginRequest.getEncryptedData(), sessionKey, loginRequest.getIv());if (encryptedData != null){String unionId = encryptedData.getString("unionId");wechatUserDO.setUnionId(unionId);}}return wechatUserDO;}private JSONObject getEncryptedData(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 + 1;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) {log.error("解密加密信息报错", e.getMessage());}return null;}//生成token 这里可以忽略 根据自己当前业务系统选取生成方式public ResponseResult createToken(WechatUser wechatUser) {String openid = wechatUser.getOpenId();String token = MD5Util.getMD5Str(openid + System.currentTimeMillis());String flyingSessionId = MD5Util.getMD5Str("HAHA" + wechatUser.getOpenId());wechatUser.getStringRedisTemplate().opsForValue().set(token, wechatUser.getNickname());//外部登录生成tokenString key = token + flyingSessionId;Map<String, String> redisData = new HashMap<>();redisData.put("HAHA-TOKEN", token);redisData.put("HAHA-SESSIONID", flyingSessionId);redisData.put("uid", wechatUser.getId() + "");redisData.put("openid", wechatUser.getOpenId());redisData.put("nickname", wechatUser.getNickname());wechatUser.getStringRedisTemplate().opsForHash().putAll(key, redisData);wechatUser.getStringRedisTemplate().expire(key, 86400, TimeUnit.SECONDS);return ResponseResult.okResult(redisData);}}

注意:

微信小程序更新后:

#### 前端调用接口 参数一次性给齐 这样就可以一次调用 获取所有;

java对接微信小程序(登录获取用户信息)相关推荐

  1. Java实现微信小程序登录 获取用户信息

    小程序比公众号授权登录 更加简单 其实没什么是后台需要处理的 前端传过来一个code 我们保存以下通过code获取过来的openid就可以 其他的用户信息 前端小程序那边可以获取. 首先既然是小程序登 ...

  2. 微信小程序授权获取用户信息和手机号码

    微信小程序授权获取用户信息和手机号码 1.微信官方文档 登录:https://developers.weixin.qq.com/miniprogram/dev/framework/open-abili ...

  3. 微信小程序制作——获取用户信息

    微信小程序制作--获取用户信息 1.获取用户信息 方式一 wxml <view bindtap="getUserName">获取当前用户名</view> j ...

  4. 微信小程序授权 获取用户信息

    微信小程序授权 获取用户信息 小程序昵称突然变成了"微信用户",头像也不显示, <!-- 近期很多小伙伴通过该方法获取头像和昵称,代码也没有做改变,突然就变成了下面这样子 - ...

  5. Java-(二)微信小程序授权获取用户信息和手机号码

    第一篇我们已经知道了微信小程序怎么授权登录获取用户信息. openId 和 unionId .下面将高速告诉大家,微信小程序如何授权获取用户信息和手机号码. 微信官方文档:https://develo ...

  6. 【微信小程序】获取用户信息

    文章目录 获取用户信息 组件open-data button组件中的open-type 接口getUserProfile 查看授权结果 获取用户信息 组件open-data 组件 open-data用 ...

  7. 微信小程序后端获取用户信息

    @塞纳河 微信小程序通过解密encrytedData(iv.sessionKey),获取用户信息 appid: 应用唯一标识 secret:应用密钥 code:wx.login()获取 encrypt ...

  8. 微信小程序如何获取用户信息

    自我介绍 我是IT果果日记,微信公众号请搜索 IT果果日记 一个普通的技术宅,定期分享技术文章,欢迎点赞.关注和转发,请多关照. 微信小程序用户基本信息有哪些? 除了基本信息,微信还会提供openId ...

  9. 玩转微信小程序 之 获取用户信息以及玩转基本列表渲染(2019/04/14)

    LZ-Says:总是要各种颠沛流离,才能换得片刻安宁.努力让自己变得更好,加油- 前言 前几天,完成了微信小程序的首章,学习起来,还是多多少少有点坑,不舒服. 今天我们继续开启微信小程序 Study ...

  10. 微信小程序开发----获取用户信息

    今天介绍两种微信小程序获取用户信息的方法 第一中直接授权获取(在同一页面之中): 首先在微信程序一个页面的WXML文件写入获取用户信息的按钮 <!-- bindTap用于绑定事件 --> ...

最新文章

  1. JVM 虚拟机图文详解!真香!秒懂!一点都不难!
  2. linux 下ssh端口反弹,利用ssh隧道反弹shell
  3. Cloudera Manager是什么?
  4. Python输入多行多组数据两个两求和
  5. 笨人可以学计算机吗,为什么有的笨人一旦开窍,其人生就像开了挂似的呢?
  6. leetcode 290. 单词规律(hash)
  7. 计算机二维动画的核心技术是什么意思,数字化技术在二维动画设计中的应用研究...
  8. CICD详解(十五)——Jenkins插件安装失败解决
  9. Mediasoup之RateCalculator(流量统计)
  10. openbmc开发30:webui开发—基础
  11. 数竞党必看!数学竞赛权威赛事大合集,先马后看
  12. 微信小程序测试点汇总
  13. matlab自带的音乐,MATLAB乐器(如何用matlab演奏音乐)
  14. 微信小程序搭建项目起步
  15. SSH框架电力项目八--运行监控的保存
  16. 地理坐标系、大地坐标系与地图投影与重投影详解
  17. uni-app小程序使用小程序码绑定用户信息合成海报
  18. 基于高校服务器信息的网络空间资源分类
  19. 2020年有寓意的领证日期_2020年有寓意的领证日期
  20. 良心安利通用模板素材网站

热门文章

  1. 用核化的相关滤波器来高速跟踪
  2. 收藏、学习一气呵成,2019年机器之心干货教程都在这里了
  3. 开发中常用到adb命令
  4. 2018年计算机技术考哪几门,2018年计算机技术在职研究生考试科目具体是什么
  5. Linux文件管理、标准I/O重定向和管道以及Linux用户、组和权限知识总结
  6. WINDOWSSoftwareDistribution这目录可以删除吗
  7. 第七章:使用Netlify零成本部署组件文档
  8. RTT之硬件定时器使用
  9. 蜗牛学院2020年08月11号作业
  10. 博士申请 | 悉尼科技大学招收数据科学/机器学习方向全奖博士生