redis map相关操作

hset

hmset

hincrBy

del

hget 

hgetall  

exist

package com.telcoos.iam.cache.service.welcome;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import redis.clients.jedis.exceptions.JedisException;

import com.huawei.bsp.log.OssLog;
import com.huawei.bsp.log.OssLogFactory;
import com.huawei.iam.cbb.security.PXXGenerater;
import com.huawei.iam.cbb.util.CipherUtil;
import com.huawei.iam.common.audit.AuditItem.AuditResult;
import com.huawei.iam.common.redis.IAMRedis;
import com.telcoos.iam.cache.service.util.AuditAuthEx;

/**
* 欢迎邮件所有涉及的redis相关内容处理类
*
*/
public class WelEmailRedis
{
private static final OssLog logger = OssLogFactory.getLogger(WelEmailRedis.class);

private static final int SEVEN_DAYS_SECOND = 7 * 24 * 60 * 60;

private static final String WELCOME_EMAIL_PREFIX_KEY = "global.users.welcome-email:";

private static final String FIELD_OTP_VALUE = "optValue";

private static final String FIELD_OTP_CREATE_TIME = "createTime";

private static final String FIELD_OTP_WRONG_TIMES = "otpWrongTimes";

private static final String FIELD_RESEND_TIMES = "resendTimes";

private static final String CREATE_USER_EMAIL = "createAdmEmail";

private static final String IS_RESET_PWD = "isResetPwd";

private String userId;

/**
* 构造函数
*
* @param userId
* userId
*/
public WelEmailRedis(String userId)
{
this.userId = userId;
}

/**
* 更新OTP
*
* @return 更新后的OTP
*/
public String updateOTP()
{
String key = WELCOME_EMAIL_PREFIX_KEY + userId;
String otp = PXXGenerater.generatePwd(32, 3);
try(IAMRedis conn = IAMRedis.createConnection())
{
conn.hset(key, FIELD_OTP_VALUE, otp);
conn.hset(key, FIELD_OTP_CREATE_TIME, String.valueOf(System.currentTimeMillis()));
}
catch (JedisException ex)
{
logger.error("check otp from redis failed");
return otp;
}
return otp;
}

/**
* 生成OTP
*
* @return 新生成的OTP
*/
public String createNewOTP(String userEmail, boolean isResetPwd)
{
String key = WELCOME_EMAIL_PREFIX_KEY + userId;
String otp = PXXGenerater.generatePwd(32, 3);
try(IAMRedis conn = IAMRedis.createConnection())
{
Map<String, String> otpMap = new HashMap<String, String>();
otpMap.put(FIELD_OTP_VALUE, otp);
otpMap.put(FIELD_OTP_CREATE_TIME, String.valueOf(System.currentTimeMillis()));
otpMap.put(FIELD_RESEND_TIMES, "0");
otpMap.put(CREATE_USER_EMAIL, (userEmail == null || userEmail.isEmpty()) ? userEmail : CipherUtil.encrypt(userEmail));
otpMap.put(IS_RESET_PWD, String.valueOf(isResetPwd));

conn.hmset(key, otpMap);
conn.expire(key, SEVEN_DAYS_SECOND);
}
catch (JedisException ex)
{
logger.error("save otp to redis failed");
return otp;
}
return otp;
}

/**
* 链接已经过期或者链接不存在
*
* @return 链接是否过期或不存在
*/
public boolean isURLNotExistOrExpired()
{
boolean exist = true;
try(IAMRedis conn = IAMRedis.createConnection())
{
exist = conn.exists(WELCOME_EMAIL_PREFIX_KEY + userId);
}
catch (JedisException e)
{
logger.error("get otp from redis failed", e);
}
return !exist;
}

/**
* 是否到达OTP允许传错的最大次数
*
* @return 到达OTP允许传错的最大次数
*/
public boolean isOverOtpWrongLimitTimes()
{
String resTimes = getValueByKey(FIELD_OTP_WRONG_TIMES);
if (resTimes == null)
{
return false;
}
return Integer.parseInt(resTimes) >= 5;
}

/**
* 是否是篡改的OTP
*
* @param otpInUrl
* 欢迎邮件发送的链接
* @return 篡改的OTP
*/
public boolean isFakeOTP(String otpInUrl)
{
String otpInRedis = getValueByKey(FIELD_OTP_VALUE);
return !otpInUrl.equals(otpInRedis);
}

/**
* 获取OTP的创建时间
*
* @return otp创建时间
*/
public long getCreateOtpUTCTime()
{
String time = getValueByKey(FIELD_OTP_CREATE_TIME);
if (time == null)
{
return 0L;
}
return Long.parseLong(time);
}

/**
* 获取重发次数
*
* @return
*/
public int getResendTimes()
{
String resendStr = getValueByKey(FIELD_RESEND_TIMES);
if (resendStr == null || resendStr.isEmpty())
{
return 1;
}
return Integer.parseInt(resendStr);
}

/**
* 获取创建用户
*
* @return create user email
*/
public String getCreateUserEmail()
{
return CipherUtil.decryptWithCompatible(getValueByKey(CREATE_USER_EMAIL));
}

public String isResetPwd()
{
String val = getValueByKey(IS_RESET_PWD);
if (StringUtils.isEmpty(val))
{
return "true";
}
return val;
}

private String getValueByKey(String key)
{
try(IAMRedis conn = IAMRedis.createConnection())
{
return conn.hget(WELCOME_EMAIL_PREFIX_KEY + userId, key);
}
catch (JedisException e)
{
logger.error("welcome email getFromRedis failed" + key, e);
}
return null;
}

/**
* otp错误次数自增
*/
public void incrOtpWrongTimes()
{
try(IAMRedis conn = IAMRedis.createConnection())
{
conn.hincrBy(WELCOME_EMAIL_PREFIX_KEY + userId, FIELD_OTP_WRONG_TIMES, 1);
}
catch (JedisException ex)
{
logger.error("set user info error to redis", ex);
}
}

/**
* resend次数自增
*/
public void incrResendTimes()
{
try(IAMRedis conn = IAMRedis.createConnection())
{
conn.hincrBy(WELCOME_EMAIL_PREFIX_KEY + userId, FIELD_RESEND_TIMES, 1);
}
catch (JedisException ex)
{
logger.error("set user info error to redis", ex);
}
}

/**
* 清除发送邮件相关的所有redis数据
*/
public void removeAllData()
{
try(IAMRedis conn = IAMRedis.createConnection())
{
conn.del(WELCOME_EMAIL_PREFIX_KEY + userId);
}
catch (JedisException e)
{
logger.error("", e);
}
}


public boolean checkURLWithRedies(AuditAuthEx audit, String otp){
// 过期性校验与处理
if (isURLNotExistOrExpired())
{
logger.error("welcomeEmail is expired: " + userId);
return false;
}
// 24小时内,一个userid只能点击5次
if (isOverOtpWrongLimitTimes())
{
// DELETE all otp infos
removeAllData();
logger.error("welcomeEmail is over wrong otp limit:" + userId);
return false;
}

// 用户ID做了频率控制,从有用户ID的地方开始做审记,不会导致日志泛滥
audit.setUser(userId, null, null, null);

// otp不匹配(场景:被篡改,恶意攻击尝试)
if (isFakeOTP(otp))
{
audit.record(AuditResult.FAILURE, "welcomeEmail otp is wrong.");
incrOtpWrongTimes();
logger.error("welcomeEmail otp is wrong:" + userId);
return false;
}

return true;
}
}

猜你喜欢

转载自www.cnblogs.com/mushimeng/p/9634888.html