1、数据库设计
2、明文密码两次md5处理
考虑到如果数据包被截取,明文密码可能会泄露,在上传时将密码进行md5固定salt加密,在接收后存入数据库时再进行随机salt,md5加密,将md5和salt同事写入数据库中。具体操作如下:
第一步当然是引入MD5的依赖,
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
接下来可以创建具体的实现类了
数据库中的salt当然不能直接用,直接等于没用,可以通过代码改动,拼接部分salt
public static String md5(String src){
return DigestUtils.md5Hex(src);
}
private static final String salt="1a2b3c4d";//固定,与密码拼装
public static String inputPassFormPass(String inputPass){
String str="" + salt.charAt(0)+salt.charAt(2)+inputPass+salt.charAt(5)+salt.charAt(4);
return md5(str);
}
反查彩虹表后得到的数据时=是密码+拼接的salt
再次将得到的拼接密码MD5加密,此时可以随机定义salt
public static String formPassToDBPass(String formPass,String salt){
String str="" + salt.charAt(0)+salt.charAt(2)+formPass+salt.charAt(5)+salt.charAt(4);
return md5(str);
}
接下来将用户输入的明文密码转化成数据库密码
public static String inputPassToDbPass(String input,String saltDB){
String formPass=inputPassFormPass(input);
String dbPass=formPassToDBPass(formPass,saltDB);
return dbPass;
}
可以建立新的数据库表格了,切记密码为第二次加密后的
登录功能实现
首先,在controller里面添加方法,实现登陆界面的显示,其中login为html前端界面
@RequestMapping("to_login")
public String tologin(){
return "login";
}
1、页面
需要的静态bss
bootstrap来画页面,jquery-valition---foom表单验证,layer做弹框,MD5.js做md5,引入相关的js和css页面,(引入静态文件@+{}+具体路径)
点击登陆后
script function提供参数校验,如果通过,dologin使用ajx异步提交,并且打开layer框,通过success,errir回调,无论上次僬侥结果如何,都关闭layer。再data中获取id及密码,其中密码通过md5加密后的。
3、JSR303参数校验+全局异常处理器
loginvo(接收参数)
在controler中接收,首先判断参数(参数校验)如果校验失败返回错误页面
通过正则表达式Matcher和Pattern来判断手机号的格式
private static final Pattern mobile_pattern=Pattern.compile("1\\d{10}");
自定义注解
@interface,在底层实现上,所有定义的注解都会自动继承java.lang.annotation.Annotation接口。
4、全局异常处理
@ControllerAdvice 可以实现三个方面的功能:
- 全局异常处理
- 全局数据绑定
- 全局数据预处理
5、分布式Session
为实现登陆数据的定时保存,现将token数据保存到cookie,并且存到redis中<token,user>,,编写getbytoken来得到user并新定义cookie
private void addCookie(HttpServletResponse response,String token,MiaoshaUser user){
//System.out.println("生成cookie");
redisService.set(MiaoshaUserKey.token,token,user);
Cookie cookie=new Cookie(COOKI_NAME_TOKEN,token);
cookie.setMaxAge(MiaoshaUserKey.token.expireSeconds());
cookie.setPath("/");
response.addCookie(cookie);
}
public MiaoshaUser getByToken(HttpServletResponse response,String token) {
if (StringUtils.isEmpty(token))
return null;
MiaoshaUser user= redisService.get(MiaoshaUserKey.token,token,MiaoshaUser.class);
//延长有效期
//生成cookie
if (user!=null){
addCookie(response,token,user);
}
return user;
}
重写confige,使controller更简洁有效
@Service
public class userArgumentResolvers implements HandlerMethodArgumentResolver {
@Autowired
miaoshauserservice userService;
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
Class<?> clazz=methodParameter.getParameterType();
return clazz== miaoshauser.class;
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
HttpServletRequest request=nativeWebRequest.getNativeRequest(HttpServletRequest.class);
HttpServletResponse response=nativeWebRequest.getNativeResponse(HttpServletResponse.class);
String paramToken=request.getParameter(miaoshauserservice.COOKIE_NAME_TOKEN);
String cookieToken=getCookieValue(request,miaoshauserservice.COOKIE_NAME_TOKEN);
if (org.apache.commons.lang3.StringUtils.isEmpty(cookieToken)&& org.apache.commons.lang3.StringUtils.isEmpty(paramToken))
return null;
String token= StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
miaoshauser user=userService.getbytoken(response,token);
return user;
}
private String getCookieValue(HttpServletRequest request, String cookiName) {
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals(cookiName))
return cookie.getValue();
}
return null;
}
出现的错误
修改完以上config及接下来的qq登陆使用的依赖后,运行代码显示前端代码找不到,具体如下:
后来经过百度,有大神建议在config添加如下代码
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!registry.hasMappingForPattern("/webjars/**")) {
registry.addResourceHandler("/webjars/**").addResourceLocations(
"classpath:/META-INF/resources/webjars/");
}
if (!registry.hasMappingForPattern("/**")) {
registry.addResourceHandler("/**").addResourceLocations(
CLASSPATH_RESOURCE_LOCATIONS);
}
问题解决