当前位置:   article > 正文

小程序微信登录功能的实现_微信小程序微信登录代码

微信小程序微信登录代码
业务代码
  1. /**
  2. * 微信登录
  3. */
  4. @Override
  5. @Transactional(rollbackFor = Exception.class)
  6. public AjaxResult wxLogin(WeChatCodeRequest request, HttpServletRequest httpServletRequest) {
  7. String code = request.getCode();
  8. //通过code获取手机号
  9. JSONObject jsonObject = WechatUtil.getPhoneNumber(code);
  10. JSONObject js = (JSONObject) jsonObject.get("phone_info");
  11. String phoneNumber = (String) js.get("phoneNumber");
  12. //对手机号进行判断,登录
  13. //剩下的是校验成功的情况
  14. if (iSysUserService.getLoginUserByPhone(phoneNumber) == null) {
  15. return AjaxResult.error("登录失败,用户不存在或不可用,请联系管理员注册");
  16. } else {
  17. AjaxResult ajax = new AjaxResult();
  18. //说明在User表中已经存在,则将二者绑定到一起,使用user信息进行登录
  19. redisCache.deleteObject(CacheConstants.CAPTCHA_CODE_KEY + phoneNumber);
  20. // LoginUser loginUser = tokenService.getLoginUser(httpServletRequest);
  21. LoginUser loginUser = iSysUserService.getLoginUserByPhone(phoneNumber);
  22. List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, loginUser.getUserId()));
  23. List<SysRole> collect = sysUserRoles.stream().map(i -> {
  24. //拿着roleid查询role
  25. SysRole sysRole = roleMapper.selectRoleById(i.getRoleId());
  26. return sysRole;
  27. }).collect(Collectors.toList());
  28. LambdaUpdateWrapper<SysUser> uw = new LambdaUpdateWrapper<SysUser>()
  29. .set(SysUser::getLoginIp, ServletUtil.getClientIP(httpServletRequest))
  30. .set(SysUser::getLoginDate, new Date())
  31. .set(SysUser::getUpdateTime, new Date())
  32. .eq(SysUser::getPhonenumber, phoneNumber)
  33. .eq(SysUser::getStatus, "0")
  34. .eq(SysUser::getDelFlag, "0");
  35. iSysUserService.update(uw);
  36. // 生成token
  37. //设置角色
  38. loginUser.getUser().setRoles(collect);
  39. //设置权限
  40. // loginUser.setPermissions();
  41. String token = tokenService.createToken(loginUser);
  42. ajax.put(Constants.TOKEN, token);
  43. tokenService.setLoginUser(loginUser);
  44. return ajax;
  45. }
  46. }
  tokenService工具类
  1. package mmm.crm.system.web.service;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import java.util.concurrent.TimeUnit;
  5. import javax.servlet.http.HttpServletRequest;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.beans.factory.annotation.Value;
  8. import org.springframework.stereotype.Component;
  9. import mmm.crm.common.constant.CacheConstants;
  10. import mmm.crm.common.constant.Constants;
  11. import mmm.crm.common.core.domain.model.LoginUser;
  12. import mmm.crm.common.core.redis.RedisCache;
  13. import mmm.crm.common.utils.ServletUtils;
  14. import mmm.crm.common.utils.StringUtils;
  15. import mmm.crm.common.utils.ip.AddressUtils;
  16. import mmm.crm.common.utils.ip.IpUtils;
  17. import mmm.crm.common.utils.uuid.IdUtils;
  18. import eu.bitwalker.useragentutils.UserAgent;
  19. import io.jsonwebtoken.Claims;
  20. import io.jsonwebtoken.Jwts;
  21. import io.jsonwebtoken.SignatureAlgorithm;
  22. /**
  23. * token验证处理
  24. */
  25. @Component
  26. public class TokenService {
  27. // 令牌自定义标识
  28. @Value("${token.header}")
  29. private String header;
  30. // 令牌秘钥
  31. @Value("${token.secret}")
  32. private String secret;
  33. // 令牌有效期(默认30分钟)
  34. @Value("${token.expireTime}")
  35. private int expireTime;
  36. protected static final long MILLIS_SECOND = 1000;
  37. protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
  38. private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
  39. @Autowired
  40. private RedisCache redisCache;
  41. /**
  42. * 获取用户身份信息
  43. *
  44. * @return 用户信息
  45. */
  46. public LoginUser getLoginUser(HttpServletRequest request) {
  47. // 获取请求携带的令牌
  48. String token = getToken(request);
  49. if (StringUtils.isNotEmpty(token)) {
  50. try {
  51. Claims claims = parseToken(token);
  52. // 解析对应的权限以及用户信息
  53. String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
  54. String userKey = getTokenKey(uuid);
  55. LoginUser user = redisCache.getCacheObject(userKey);
  56. return user;
  57. } catch (Exception e) {
  58. }
  59. }
  60. return null;
  61. }
  62. /**
  63. * 设置用户身份信息
  64. */
  65. public void setLoginUser(LoginUser loginUser) {
  66. if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
  67. refreshToken(loginUser);
  68. }
  69. }
  70. /**
  71. * 删除用户身份信息
  72. */
  73. public void delLoginUser(String token) {
  74. if (StringUtils.isNotEmpty(token)) {
  75. String userKey = getTokenKey(token);
  76. redisCache.deleteObject(userKey);
  77. }
  78. }
  79. /**
  80. * 创建令牌
  81. *
  82. * @param loginUser 用户信息
  83. * @return 令牌
  84. */
  85. public String createToken(LoginUser loginUser) {
  86. String token = IdUtils.fastUUID();
  87. loginUser.setToken(token);
  88. setUserAgent(loginUser);
  89. refreshToken(loginUser);
  90. Map<String, Object> claims = new HashMap<>();
  91. claims.put(Constants.LOGIN_USER_KEY, token);
  92. return createToken(claims);
  93. }
  94. /**
  95. * 验证令牌有效期,相差不足20分钟,自动刷新缓存
  96. *
  97. * @param loginUser
  98. * @return 令牌
  99. */
  100. public void verifyToken(LoginUser loginUser) {
  101. long expireTime = loginUser.getExpireTime();
  102. long currentTime = System.currentTimeMillis();
  103. if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
  104. refreshToken(loginUser);
  105. }
  106. }
  107. /**
  108. * 刷新令牌有效期
  109. *
  110. * @param loginUser 登录信息
  111. */
  112. public void refreshToken(LoginUser loginUser) {
  113. loginUser.setLoginTime(System.currentTimeMillis());
  114. loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
  115. // 根据uuid将loginUser缓存
  116. String userKey = getTokenKey(loginUser.getToken());
  117. redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
  118. }
  119. /**
  120. * 设置用户代理信息
  121. *
  122. * @param loginUser 登录信息
  123. */
  124. public void setUserAgent(LoginUser loginUser) {
  125. UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
  126. String ip = IpUtils.getIpAddr();
  127. loginUser.setIpaddr(ip);
  128. loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
  129. loginUser.setBrowser(userAgent.getBrowser().getName());
  130. loginUser.setOs(userAgent.getOperatingSystem().getName());
  131. }
  132. /**
  133. * 从数据声明生成令牌
  134. *
  135. * @param claims 数据声明
  136. * @return 令牌
  137. */
  138. private String createToken(Map<String, Object> claims) {
  139. String token = Jwts.builder()
  140. .setClaims(claims)
  141. .signWith(SignatureAlgorithm.HS512, secret).compact();
  142. return token;
  143. }
  144. /**
  145. * 从令牌中获取数据声明
  146. *
  147. * @param token 令牌
  148. * @return 数据声明
  149. */
  150. private Claims parseToken(String token) {
  151. return Jwts.parser()
  152. .setSigningKey(secret)
  153. .parseClaimsJws(token)
  154. .getBody();
  155. }
  156. /**
  157. * 从令牌中获取用户名
  158. *
  159. * @param token 令牌
  160. * @return 用户名
  161. */
  162. public String getUsernameFromToken(String token) {
  163. Claims claims = parseToken(token);
  164. return claims.getSubject();
  165. }
  166. /**
  167. * 获取请求token
  168. *
  169. * @param request
  170. * @return token
  171. */
  172. public String getToken(HttpServletRequest request) {
  173. String token = request.getHeader(header);
  174. if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
  175. token = token.replace(Constants.TOKEN_PREFIX, "");
  176. }
  177. return token;
  178. }
  179. private String getTokenKey(String uuid) {
  180. return CacheConstants.LOGIN_TOKEN_KEY + uuid;
  181. }
  182. }

 微信登录工具类

  1. package mmm.crm.common.utils;
  2. import cn.hutool.http.Header;
  3. import cn.hutool.http.HttpRequest;
  4. import cn.hutool.http.HttpResponse;
  5. import cn.hutool.http.HttpUtil;
  6. import cn.hutool.json.JSONUtil;
  7. import com.alibaba.fastjson2.JSON;
  8. import com.alibaba.fastjson2.JSONObject;
  9. import com.google.common.net.HttpHeaders;
  10. import com.google.gson.Gson;
  11. import com.google.gson.JsonObject;
  12. import lombok.extern.log4j.Log4j;
  13. import mmm.crm.common.utils.http.HttpUtils;
  14. import mmm.crm.common.utils.sign.Base64;
  15. import org.apache.http.HttpEntity;
  16. import org.apache.http.client.methods.CloseableHttpResponse;
  17. import org.apache.http.client.methods.HttpGet;
  18. import org.apache.http.impl.client.DefaultHttpClient;
  19. import org.apache.http.util.EntityUtils;
  20. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  21. import org.springframework.beans.factory.annotation.Autowired;
  22. import org.springframework.web.bind.annotation.PostMapping;
  23. import org.springframework.web.bind.annotation.RequestParam;
  24. import org.springframework.web.client.RestTemplate;
  25. import javax.crypto.BadPaddingException;
  26. import javax.crypto.Cipher;
  27. import javax.crypto.IllegalBlockSizeException;
  28. import javax.crypto.NoSuchPaddingException;
  29. import javax.crypto.spec.IvParameterSpec;
  30. import javax.crypto.spec.SecretKeySpec;
  31. import javax.servlet.FilterConfig;
  32. import javax.xml.bind.ValidationException;
  33. import java.io.IOException;
  34. import java.io.UnsupportedEncodingException;
  35. import java.security.*;
  36. import java.security.spec.InvalidParameterSpecException;
  37. import java.util.Arrays;
  38. import java.util.HashMap;
  39. import java.util.Map;
  40. /**
  41. * @Author:XGY
  42. * @Date:2023/4/24 18:14
  43. */
  44. public class WechatUtil {
  45. public static JSONObject getSessionKeyOrOpenId(String code) throws IOException {
  46. //微信端登录code
  47. String wxCode = code;
  48. String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
  49. Map<String, String> requestUrlParam = new HashMap<>();
  50. //小程序appId
  51. requestUrlParam.put("appid", "wx88c4501ad86e1174");
  52. //小程序secret
  53. requestUrlParam.put("secret", "c08515ced6cd60e976028be5d0d43498");
  54. //小程序端返回的code
  55. requestUrlParam.put("js_code", wxCode);
  56. //默认参数
  57. requestUrlParam.put("grant_type", "authorization_code");
  58. //发送post请求读取调用微信接口获取openid用户唯一标识
  59. JSONObject jsonObject = JSON.parseObject(HttpClientUtil.doPost(requestUrl, requestUrlParam));
  60. return jsonObject;
  61. }
  62. public static com.alibaba.fastjson2.JSONObject getUserInfo(String encryptedData, String sessionKey, String iv) {
  63. // 被加密的数据
  64. byte[] dataByte = Base64.decode(encryptedData);
  65. // 加密秘钥
  66. byte[] keyByte = Base64.decode(sessionKey);
  67. // 偏移量
  68. byte[] ivByte = Base64.decode(iv);
  69. try {
  70. // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
  71. int base = 16;
  72. if (keyByte.length % base != 0) {
  73. int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
  74. byte[] temp = new byte[groups * base];
  75. Arrays.fill(temp, (byte) 0);
  76. System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
  77. keyByte = temp;
  78. }
  79. // 初始化
  80. Security.addProvider(new BouncyCastleProvider());
  81. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
  82. SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
  83. AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
  84. parameters.init(new IvParameterSpec(ivByte));
  85. cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
  86. byte[] resultByte = cipher.doFinal(dataByte);
  87. if (null != resultByte && resultByte.length > 0) {
  88. String result = new String(resultByte, "UTF-8");
  89. return JSON.parseObject(result);
  90. }
  91. } catch (Exception e) {
  92. new Exception(e);
  93. }
  94. return null;
  95. }
  96. // public static String getPhone(String code) throws ValidationException, IOException {
  97. // final String appID = "wx88c4501ad86e1174";
  98. // final String appSecret = "c08515ced6cd60e976028be5d0d43498";
  99. // //使用appid和密钥获取access_token
  100. String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appID + "&secret=" + appSecret;
  101. String s = HttpUtils.sendGet(url);
  102. JSONObject jsonObject = HttpUtils.doGetJson(url);
  103. // //使用access_token和code获取手机号
  104. // JSONObject accessToken = getAccessToken(appID, appSecret);
  105. // String url1 = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken.getString("access_token");
  106. // JSONObject data = new JSONObject();
  107. // data.put("code", code);
  108. // String phoneNumber = null;
  109. // try {
  110. // JSONObject jsonObject1 = HttpUtils.doPost(url1, code);
  111. // JSONObject phone_info = (JSONObject) jsonObject1.get("phone_info");
  112. // phoneNumber = phone_info.getString("phoneNumber");
  113. // } catch (Exception e) {
  114. // throw new RuntimeException(e);
  115. // }
  116. // return phoneNumber;
  117. // }
  118. // public static JSONObject getAccessToken(String appid, String secretKey) {
  119. // String result = null;
  120. // try {
  121. // String baseUrl = "https://api.weixin.qq.com/cgi-bin/token";
  122. // HashMap<String, Object> requestParam = new HashMap<>();
  123. // // 小程序 appId
  124. // requestParam.put("grant_type", "client_credential");
  125. // // 小程序唯一凭证id
  126. // requestParam.put("appid", appid);
  127. // // 小程序 appSecret(小程序的唯一凭证密钥)
  128. // requestParam.put("secret", secretKey);
  129. // // 发送GET请求读取调用微信接口获取openid用户唯一标识
  130. // result = HttpUtil.get(baseUrl, requestParam);
  131. // } catch (Exception e) {
  132. // e.printStackTrace();
  133. // }
  134. // return JSONObject.parseObject(result);
  135. // }
  136. public static String getAccessTokenOne(String appId,String appSecret) {
  137. String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
  138. + appId + "&secret=" + appSecret;
  139. System.out.println("request user info from url: {" + url + "}");
  140. JsonObject accessTokenInfo = null;
  141. try {
  142. DefaultHttpClient httpClient = new DefaultHttpClient();
  143. HttpGet httpGet = new HttpGet(url);
  144. CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
  145. HttpEntity entity = httpResponse.getEntity();
  146. String response = EntityUtils.toString(entity, "utf-8");
  147. //LOGGER.error("获取Token-------------------"+response);
  148. Gson token_gson = new Gson();
  149. accessTokenInfo = token_gson.fromJson(response, JsonObject.class);
  150. return accessTokenInfo.get("access_token").toString().replaceAll("\"", "");
  151. } catch (Exception ex) {
  152. System.out.println("fail to request wechat user info. [error={" + ex + "}]");
  153. }
  154. return "";
  155. }
  156. /**
  157. * 请求微信接口服务,用code换取用户手机号(每个code只能使用一次,code的有效期为5min)
  158. * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/phonenumber/phonenumber.getPhoneNumber.html
  159. *
  160. * @param code
  161. * @param accessToken
  162. * @return
  163. */
  164. public static JSONObject getPhoneNumber(String code) {
  165. final String appID = "wx88c4501ad86e1174";
  166. final String appSecret = "c08515ced6cd60e976028be5d0d43498";
  167. String accessTokenOne = getAccessTokenOne(appID, appSecret);
  168. String result = null;
  169. try {
  170. // 接口调用凭证:accessToken
  171. String baseUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessTokenOne;
  172. HashMap<String, Object> requestParam = new HashMap<>();
  173. // 手机号调用凭证
  174. requestParam.put("code", code);
  175. // 发送post请求读取调用微信接口获取openid用户唯一标识
  176. String jsonStr = JSONUtil.toJsonStr(requestParam);
  177. HttpResponse response = HttpRequest.post(baseUrl)
  178. .header(Header.CONTENT_ENCODING, "UTF-8")
  179. // 发送json数据需要设置contentType
  180. .header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded")
  181. .body(jsonStr)
  182. .execute();
  183. if (response.getStatus() == HttpStatus.SUCCESS) {
  184. result = response.body();
  185. }
  186. } catch (Exception e) {
  187. e.printStackTrace();
  188. }
  189. return JSONObject.parseObject(result);
  190. }
  191. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/684865
推荐阅读
相关标签
  

闽ICP备14008679号