发表于: 2018-01-08 22:07:35
3 491
今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了Margin)
今天完成了对用户注册的加密,以及登陆验证,验证跳转.
先展示一下登陆页面效果:
登陆成功会进入joblist这个页面:
账户名或者密码错误会在当前页面刷新,并给予提示:
看下代码:
首先是注册的密码加密这块儿:
加密的类我进行了重构,用自己的思路进行了重写.
package com.util;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* @author Arike
* Create_at 2018/1/8 11:10
* 该类用于密码加密和验证的操作
*/
public class Encrypt {
private Encrypt() { }
/**
* 利用java原生的摘要实现SHA256加密
* @param str 加密后的报文
* @return 存储到服务器的密码
*/
public static String getSHA256Str(String str){
MessageDigest messageDigest;
String encodeStr="";
try {
messageDigest= MessageDigest.getInstance("SHA-512");
messageDigest.update(str.getBytes("UTF-8"));
encodeStr=byte2Hex(messageDigest.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return encodeStr;
}
/**
* 将byte转为16进制
* @param bytes 传入加密了过后的byte密码
* @return 返回给加密方法操作的密码字符串
*/
private static String byte2Hex(byte[] bytes) {
StringBuffer stringBuffer = new StringBuffer();
String temp = null;
for (byte aByte : bytes) {
temp = Integer.toHexString(0Xff/*255*/ & aByte);//使用0Xff其实是使用1111 1111八个二进制位
if(temp.length()==1){ //但这里是作为int字面值来做的,所以他的二进制
// 得到只有1位的时候在后面补0 应该为0000 0000 0000 0000 0000 0000 1111 1111
stringBuffer.append("0"); //这样能保证byte为负数的时候去掉符号位.
}
stringBuffer.append(temp);
}
return stringBuffer.toString();
}
/**
*
* @return 返回一个盐值
*/
public static String getSalt(){
byte[] bytes =new byte[10];
SecureRandom sr = new SecureRandom();
sr.nextBytes(bytes);
return byte2Hex(bytes);
}
}
加密过程:
@Override
public void insertUser(User user) {
user.setCreateAt(System.currentTimeMillis());
String salt = Encrypt.getSalt();
String encode = user.getPassWord()+salt;
encode = Encrypt.getSHA256Str(encode);
user.setSalt(salt);
user.setPassWord(encode);
userDao.insertUser(user);
}
加密的过程是拿到用户的密码然后根据SecureRandom获取一个10个字节的随机数转换为16进制的字符串表现形式然后与用户密码进行拼接,拼接之后使用SHA-512算法进行加密,再转换为16进制的字符串表现形式进行存储.并且把盐值进行存储以便登陆验证使用.其实这个过程相当于进行了多次加密,这个过程是绝对不可逆的.
然后是验证登陆:
@Override
public User loginSelect(User user) {
return userDao.loginSelect(user);
}
/**
* 验证登陆
* @param user 从页面接收到数据
* @return 返回一个boolean用以判断页面的跳转
*/
public boolean checkLogin(User user){
User selectUser =loginSelect(user);
if(selectUser==null){
return false;
} else {
String checkEocode = Encrypt.getSHA256Str(user.getPassWord()+selectUser.getSalt());
if(checkEocode.equals(selectUser.getPassWord())){
return true;
}else {
return false;
}
}
}
}
在service层做了对用户名是否存在以及存在之后密码的比对,返回一个boolean值.账户密码正确为true,有一个不对为false.
然后是controller:
@RequestMapping(value = "/loginPage",method = RequestMethod.POST)
public String checkLogin(Model model,User user){
if(userServiceImpl.checkLogin(user)){
return "redirect:/u/joblist";
}else {
model.addAttribute("intro","用户名或密码错误,请重新登陆");
return "redirect:/login";
}
}
获取到true重定向到joblist,获取到false重定向回主页.
明天计划的事情:(一定要写非常细致的内容)
完成登陆状态保留以及验证功能的实现.
即实现cookie以及session.
遇到的问题:(遇到什么困难,怎么解决的)
跳转页面的时候重定向除了问题.自己把定向回自己当前页面..就无限重定向,疯狂报错.
收获:
对加密这个东西有了一定的了解,但还是很浅薄,还得加油.
评论