功能:
用户登录
用户名验证
用户注册
忘记密码: 获取问题
提交问题答案:
重置密码
获取用户信息
更新用户信息
退出登录:删除session
门户接口(11个):
1登录;2注册;3检验用户名是否有效;4获取登录用户的信息;5忘记密码;6提交问题答案;7忘记密码的重设置密码;8登录状态重置密码;
9登录状态更新用户信息;10获取当前登录用户的详情信息,并强制登录;11退出登录
注:
1 SQL查询不要使用 “ select * ”,需要哪个字段查那个
2 返回用户对象时,记得将用户密码设置为空
//将用户密码设置为空
user.setPassword(StringUtils.EMPTY);
3 修改SQL数据,将时间更新
<!--忘记密码的修改密码-->
<update id="updatePasswordByUsername" parameterType="map">
/*TODO 记得将 修改时间更新 update_time*/
update eshop_user
set password=#{password},update_time=new()
where username=#{username}
</update>
4 !!!! count(1) count这个单词与括号之间不能有空格 count (1) !!!!
<!--查询密码是否是这个用户的-->
<select id="checkPassword" parameterType="map" resultType="int">
select
count(1)
from eshop_user
where id=#{userId}
and password=#{password}
</select>
5.不要在mapper.xml里边写java的/**/ 注释
学习目标:
横向越权、纵向越权安全漏洞:纵向越权:检查role列的值,是否是属于管理员,如果是,才允许登录;
横向越权:先校验是否登录,修改的用户id从session里边获取修改数据时,新建一个User对象,将允许修改的值存放在这个对象里,使用 updateByPrimaryKeySelective方法,仅对存在的值进行修改
MD5明文加密及增加salt值:一个MD5加密小工具的使用
//MD5加密
user.setPassword(MD5Util.MD5EncodeUtf8(user.getPassword()));
工具类:
package com.eshop.util;
import org.springframework.util.StringUtils;
import java.security.MessageDigest;
/**
* Created by geely
*/
public class MD5Util {
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0) {
n += 256;
}
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
/**
* 返回大写MD5
*
* @param origin
* @param charsetname
* @return
*/
private static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname)) {
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
} else {
resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
}
} catch (Exception exception) {
}
return resultString.toUpperCase();
}
public static String MD5EncodeUtf8(String origin) {
//origin = origin + PropertiesUtil.getProperty("password.salt", "");
return MD5Encode(origin, "utf-8");
}
private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
}
guava缓存的使用:
UUID生成随机字符串:
//使用UUID生成一个随机字符串,当做token储存起来
String forgetToken= UUID.randomUUID().toString();
//创建token类保存token
TokenCache.setKey("token"+username,forgetToken);
return ServerResponce.createBySuccess(forgetToken);
token类:
package com.eshop.common;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
public class TokenCache {
//声明日志
private static Logger logger=LoggerFactory.getLogger(TokenCache.class);
//.initialCapacity(1000):设置初始化的容量; maximumSize(1000):当超过3000时,会使用LRU算法对缓存进行清理
//expireAfterAccess(12, TimeUnit.HOURS):缓存的有效期是12个小时
private static LoadingCache<String,String> localCache= CacheBuilder.newBuilder().initialCapacity(1000).maximumSize(3000).expireAfterAccess(12, TimeUnit.HOURS)
.build(new CacheLoader<String, String>() {
//默认的加载实现,当调用get方法时,找不到对应的token,就会加载这个方法
@Override
public String load(String s) throws Exception {
//为了不必要的空指针异常,返回一个字符串的 “null”
return "null";
}
});
public static void setKey(String key,String value){
/*保存key*/
localCache.put(key,value);
}
public static String getKey(String key){
String value=null;
try {
value = localCache.get(key);
if(value.equals("null")){
return null;
}
return value;
}catch (Exception e){
logger.error("localCache get error",e);
}
return null;
}
}
可复用服务响应对象的设计:一个消息响应对象
session的使用: