ssm实战(3)------用户模块
功能:
用户登录
用户名验证
用户注册
忘记密码: 获取问题
提交问题答案:
重置密码
获取用户信息
更新用户信息
退出登录:删除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的使用: