微信小程序登录

This commit is contained in:
zhangchenbiao
2023-05-29 15:28:30 +08:00
parent 112d874931
commit ba01f749c6
17 changed files with 721 additions and 1 deletions

View File

@@ -22,11 +22,17 @@ public class CommonConstants {
public static final int REFRESH_TOKEN_EXPIRE = 60*60*24*30;
public static final int THREE_DAY_SECONDS = 60*60*24*3;
/**
* 系统用户id
*/
public static final String SYSTEM_USER_ID = "system";
public static final String COMMA = ",";
public static final String MOSAICS = "#";
public static final String WX_APP_SECRET_KEY = "wx_app_secret_key:{0}";
public static final String MINI_PROGRAM_SESSION_KEY = "mini_program_session_key:{0}:{1}";
public static final int ZERO = 0;

View File

@@ -35,6 +35,10 @@ public enum ErrorCodeEnum {
ENTERPRISE_NOT_EXIST(1021020,"企业不存在",null),
USER_NOT_EXIST(1021021,"用户不存在",null),
USER_WAIT_AUDIT(1021018,"账号审核中,请联系企业管理员",null),
OPERATION_OVER_TIME(1021019, "您的操作过于频繁,休息一下~", null),
GET_APP_SECRET_ERROR(1021019, "获取secret异常", null),
WX_SERVICE_ERROR(1021020, "调用微信服务异常", null),
SESSION_KEY_ERROR(1021021, "sessionKey过期", null),
;

View File

@@ -0,0 +1,77 @@
package com.cool.store.utils;
import com.cool.store.exception.ServiceException;
import org.springframework.util.Assert;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.AlgorithmParameters;
import java.util.Arrays;
import java.util.Base64;
/**
* @author zhangchenbiao
* @FileName: AesUtil
* @Description:
* @date 2023-05-29 14:28
*/
public class AesUtil {
private static final Charset utf8 = StandardCharsets.UTF_8;
public static String genAesKey() {
return StringUtil.random(32);
}
public static String encrypt(String content, String aesTextKey) {
return Base64.getEncoder().encodeToString(encrypt(content.getBytes(utf8), aesTextKey.getBytes(utf8)));
}
public static String decrypt(String content, String aesTextKey) {
byte[] buffer = Base64.getDecoder().decode(content);
return new String(decrypt(buffer, aesTextKey.getBytes(utf8)), utf8);
}
public static byte[] encrypt(byte[] content, byte[] aesKey) {
Assert.isTrue(aesKey.length == 32, "IllegalAesKey, aesKey's length must be 32");
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
return cipher.doFinal(Pkcs7Encoder.encode(content));
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
}
public static byte[] decrypt(byte[] encrypted, byte[] aesKey) {
Assert.isTrue(aesKey.length == 32, "IllegalAesKey, aesKey's length must be 32");
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
return Pkcs7Encoder.decode(cipher.doFinal(encrypted));
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
}
public static String decryptWechat(String sessionKey, String encryptedData, String ivStr) {
try {
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
params.init(new IvParameterSpec(Base64.getDecoder().decode(ivStr)));
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(2, new SecretKeySpec(Base64.getDecoder().decode(sessionKey), "AES"), params);
return new String(Pkcs7Encoder.decode(cipher.doFinal(Base64.getDecoder().decode(encryptedData))), StandardCharsets.UTF_8);
} catch (Exception var5) {
throw new ServiceException("AES解密失败");
}
}
}

View File

@@ -0,0 +1,71 @@
package com.cool.store.utils;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
/**
* @author zhangchenbiao
* @FileName: Pkcs7Encoder
* @Description:
* @date 2023-05-29 14:29
*/
public class Pkcs7Encoder {
private static int BLOCK_SIZE = 32;
private static final Charset CHARSET = StandardCharsets.UTF_8;
/**
* 获得对明文进行补位填充的字节.
*
* @param count 需要进行填充补位操作的明文字节个数
* @return 补齐用的字节数组
*/
public static byte[] encode(int count) {
// 计算需要填充的位数
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
// 获得补位所用的字符
char padChr = chr(amountToPad);
StringBuilder tmp = new StringBuilder();
for (int index = 0; index < amountToPad; index++) {
tmp.append(padChr);
}
return tmp.toString().getBytes(CHARSET);
}
public static byte[] encode(byte[] src) {
int count = src.length;
// 计算需要填充的位数
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
if (amountToPad == 0) {
amountToPad = BLOCK_SIZE;
}
// 获得补位所用的字符
byte pad = (byte) (amountToPad & 0xFF);
byte[] pads = new byte[amountToPad];
for (int index = 0; index < amountToPad; index++) {
pads[index] = pad;
}
int length = count + amountToPad;
byte[] dest = new byte[length];
System.arraycopy(src, 0, dest, 0, count);
System.arraycopy(pads, 0, dest, count, amountToPad);
return dest;
}
public static byte[] decode(byte[] decrypted) {
int pad = decrypted[decrypted.length - 1];
if (pad < 1 || pad > BLOCK_SIZE) {
pad = 0;
}
if (pad > 0) {
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}
return decrypted;
}
private static char chr(int a) {
byte target = (byte) (a & 0xFF);
return (char) target;
}
}

View File

@@ -1372,7 +1372,16 @@ public class RedisUtilPool {
return setnx.equals(1L) ;
}
}.getResult();
}
public Boolean lock(String key){
return new Executor<Boolean>(shardedJedisPool) {
@Override
Boolean execute() {
Long setnx = jedis.setnx(key, System.currentTimeMillis() + "");
return setnx.equals(1L) ;
}
}.getResult();
}
/**

View File

@@ -0,0 +1,223 @@
package com.cool.store.utils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.util.HtmlUtils;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Pattern;
/**
* @author zhangchenbiao
* @FileName: AesUtil
* @Description:字符串相关操作
* @date 2023-05-29 14:28
*/
public class StringUtil extends org.apache.commons.lang3.StringUtils {
private static final char UPPER_A = 'A';
private static final char LOWER_A = 'a';
private static final char UPPER_Z = 'Z';
private static final char LOWER_Z = 'z';
private static final byte[] DIGITS = {
'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z'
};
/**
* 特殊字符正则sql特殊字符和空白符
*/
private static final Pattern SPECIAL_CHARS_REGEX = Pattern.compile("[`'\"|/,;()-+*%#·•<C2B7> \\s]");
/**
* 随机字符串因子
*/
private static final String INT_STR = "0123456789";
private static final String STR_STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
private static final String ALL_STR = INT_STR + STR_STR;
/**
* 首字母变小写
*
* @param str 字符串
* @return {String}
*/
public static String firstCharToLower(String str) {
char firstChar = str.charAt(0);
if (firstChar >= UPPER_A && firstChar <= UPPER_Z) {
char[] arr = str.toCharArray();
arr[0] += (LOWER_A - UPPER_A);
return new String(arr);
}
return str;
}
/**
* 首字母变大写
*
* @param str 字符串
* @return {String}
*/
public static String firstCharToUpper(String str) {
char firstChar = str.charAt(0);
if (firstChar >= LOWER_A && firstChar <= LOWER_Z) {
char[] arr = str.toCharArray();
arr[0] -= (LOWER_A - UPPER_A);
return new String(arr);
}
return str;
}
public static String appendParams(String url, Map<String, Object> params) {
if (StringUtil.isBlank(url)) {
return "";
} else if (CollectionUtils.isEmpty(params)) {
return url.trim();
} else {
StringBuilder sb = new StringBuilder(200);
params.forEach((k, v) -> sb.append(k).append("=").append(v).append("&"));
sb.deleteCharAt(sb.length() - 1);
url = url.trim();
int length = url.length();
int index = url.indexOf("?");
if (index > -1) {
if ((length - 1) == index) {
url += sb.toString();
} else {
url += "&" + sb.toString();
}
} else {
url += "?" + sb.toString();
}
return url;
}
}
/**
* 生成uuid采用 jdk 9 的形式,优化性能
*
* @return UUID
*/
public static String getUUID() {
ThreadLocalRandom random = ThreadLocalRandom.current();
long lsb = random.nextLong();
long msb = random.nextLong();
byte[] buf = new byte[32];
formatUnsignedLong(lsb, buf, 20, 12);
formatUnsignedLong(lsb >>> 48, buf, 16, 4);
formatUnsignedLong(msb, buf, 12, 4);
formatUnsignedLong(msb >>> 16, buf, 8, 4);
formatUnsignedLong(msb >>> 32, buf, 0, 8);
return new String(buf, StandardCharsets.UTF_8);
}
private static void formatUnsignedLong(long val, byte[] buf, int offset, int len) {
int charPos = offset + len;
int radix = 1 << 4;
int mask = radix - 1;
do {
buf[--charPos] = DIGITS[((int) val) & mask];
val >>>= 4;
} while (charPos > offset);
}
/**
* 转义HTML用于安全过滤
*
* @param html html
* @return {String}
*/
public static String escapeHtml(String html) {
return HtmlUtils.htmlEscape(html);
}
/**
* 清理字符串清理出某些不可见字符和一些sql特殊字符
*
* @param txt 文本
* @return {String}
*/
@Nullable
public static String cleanText(@Nullable String txt) {
if (txt == null) {
return null;
}
return SPECIAL_CHARS_REGEX.matcher(txt).replaceAll(StringUtil.EMPTY);
}
/**
* 获取标识符,用于参数清理
*
* @param param 参数
* @return 清理后的标识符
*/
@Nullable
public static String cleanIdentifier(@Nullable String param) {
if (param == null) {
return null;
}
StringBuilder paramBuilder = new StringBuilder();
for (int i = 0; i < param.length(); i++) {
char c = param.charAt(i);
if (Character.isJavaIdentifierPart(c)) {
paramBuilder.append(c);
}
}
return paramBuilder.toString();
}
/**
* 随机数生成
*
* @param count 字符长度
* @return 随机数
*/
public static String random(int count) {
return random(count, RandomType.ALL);
}
/**
* 随机数生成
*
* @param count 字符长度
* @param randomType 随机数类别
* @return 随机数
*/
public static String random(int count, RandomType randomType) {
if (count == 0) {
return "";
}
Assert.isTrue(count > 0, "Requested random string length " + count + " is less than 0.");
final ThreadLocalRandom random = ThreadLocalRandom.current();
char[] buffer = new char[count];
for (int i = 0; i < count; i++) {
if (RandomType.INT == randomType) {
buffer[i] = INT_STR.charAt(random.nextInt(INT_STR.length()));
} else if (RandomType.STRING == randomType) {
buffer[i] = STR_STR.charAt(random.nextInt(STR_STR.length()));
} else {
buffer[i] = ALL_STR.charAt(random.nextInt(ALL_STR.length()));
}
}
return new String(buffer);
}
public enum RandomType {
/**
* INT STRING ALL
*/
INT, STRING, ALL;
}
}