发表于: 2020-01-04 14:05:23
2 1036
啥也不说就是干!!!
今天完成的事情:
1、添加登录页面
<body>
<div class="header">
<div class="am-g">
<h1>后台信息系统</h1>
<p></p>
</div>
<hr/>
</div>
<div class="am-g">
<div class="am-u-lg-6 am-u-md-8 am-u-sm-centered">
<h3>欢迎登录</h3>
<hr>
<div class="am-form" id="login">
<fieldset>
<label>账号:</label>
<!-- <input type="text" minlength="11" required/> -->
<input type="text" id="mobile" name="mobile" minlength="11" value=""/>
<br>
<label for="password">密码:</label>
<input type="password" id="password"/>
<input type="hidden" id="passwords" name="password"/>
<br>
</fieldset>
<div class="am-cf">
<button class="am-btn am-btn-secondary" id="sub" type="button" onClick="login()">登录</button>
</div>
</div>
<hr>
<p>© 2018 HuiHui</p>
</div>
</div>
</body>
页面展示效果如下:
其中 onClick 方法是调用 ajax 定义的方法(Ajax 属于前端部分,这里只是简单地了解一下)
function login() {
$("#passwords").val(($("#password").val()));
if ($("#mobile").val() == '') {
myAlert("用户名不能为空");
return;
}
if ($("#passwords").val() == '') {
myAlert("密码不能为空");
return;
}
$.ajax({
url: '${pageContext.request.contextPath}/admin/login',
type: 'post',
async: false,
timeout: 5000, // 设置超时时间
data: {mobile: $("#mobile").val(), password: $("#passwords").val()},
success: function (data) {
// data = eval("(" + data + ")");
if (data.code == '0') {
window.location.href = "${pageContext.request.contextPath}/student/list";
} else {
myAlert(data.message);
}
}
})
}
先对输入框里面的值进行前端校验,比如用户名,密码格式。如果正确则发起请求
这里可以看到 url 表示接口地址,type 是提交的方法,success:funcation(data),是接口回调
其中 data 表示接口返回值。根据接口返回值进一步处理,如果成功就请求学生信息列表
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
public ResultInfo<Student> doLogin(String mobile, String password, Map<String, Object> map, HttpServletResponse response) throws Exception {
ResultInfo<Student> resultInfo = new ResultInfo<Student>();
if (mobile.equals("zhou") && MD5Utils.MD5(password).equals(MD5Utils.MD5("123"))) {
Student student = studentService.queryStudentInfoById(10);
if (student != null) {
map.put("student", student);
Date timeDate = new Date();
map.put("time", timeDate);
resultInfo.setMessage("登录成功");
resultInfo.setCode(ResultInfo.OK);
}
} else {
resultInfo.setMessage("用户名或密码错误");
resultInfo.setCode(ResultInfo.ERROR);
}
return resultInfo;
}
/student/list 请求的方法
@RequestMapping("/list")
public String list(@RequestParam(required = false,defaultValue = "1") Integer pageNum,@RequestParam(required = false,defaultValue = "10") Integer pageSize,HashMap<String,Object> map){
PageInfo<Student> ps = studentService.getStudentList(pageNum,pageSize);
map.put("stuInfos",ps.getList());
return "list";
}
启动项目,输入 http://localhost:8080/login.jsp,然后输入用户名密码,验证通过重定向到学生信息列表页
这里对于传递的密码要进行 MD5 加盐加密
/**
* 获取MD5字符串
*/
public static String getMD5(String content) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(content.getBytes());
return getHashString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private static final String SALT = "0fdfa5e5a88bebae640a5d88e7c84708";
/**
* 获取加盐的MD5字符串
*/
public static String getMD5WithSalt(String content) {
return getMD5(getMD5(content) + SALT);
}
private static String getHashString(MessageDigest digest) {
StringBuilder builder = new StringBuilder();
for (byte b : digest.digest()) {
builder.append(Integer.toHexString((b >> 4) & 0xf));
builder.append(Integer.toHexString(b & 0xf));
}
return builder.toString();
}
以上是简单的登录流程操作,那么对于一些页面或者接口怎么才能控制登录的权限,或者说要验证登录通过以后才能访问呢,这就需要 SpringMVC 拦截器对相应的请求进行拦截,然后做统一的登录验证。为了方便统一配置,要在需要验证登录的路径加 /u 前缀。
例如:/u/sutdent/list
那么对于登录校验来说,一般会在登录之后一般会将 sessionId 相关的信息保存到 cookies 中通过服务器返回给前端,下次请求前端需要将这些 cookies 信息携带,服务器接收 cookies 信息后对 session 进行校验,合法就通过,不合法就拒绝
2、Session、Cookies、Token
1) Session
session 从字面上讲,就是会话。这个就类似于你和一个人交谈,你怎么知道当前和你交谈的是张三而不是李四呢?对方肯定有某种特征(长相等)表明他就是张三。
session 也是类似的道理,服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用 cookie 的方式。
2) Cookies
cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。
cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。
- cookie只是实现session的其中一种方案。虽然是最常用的,但并不是唯一的方法。禁用cookie后还有其他方法存储,比如放在url中
- 现在大多都是Session + Cookie,但是只用session不用cookie,或是只用cookie,不用session在理论上都可以保持会话状态。可是实际中因为多种原因,一般不会单独使用
- 用session只需要在客户端保存一个id,实际上大量数据都是保存在服务端。如果全部用cookie,数据量大的时候客户端是没有那么多空间的。
- 如果只用cookie不用session,那么账户信息全部保存在客户端,一旦被劫持,全部信息都会泄露。并且客户端数据量变大,网络传输的数据量也会变大
3) Token
在Web领域基于Token的身份验证随处可见。在大多数使用Web API的互联网公司中,tokens 是多用户下处理认证的最佳方式。
以下几点特性会让你在程序中使用基于Token的身份验证
a. 无状态、可扩展
b. 支持移动设备
c. 跨程序调用
d. 安全
3、在登录操作中增加 Token
一般 token 返回给客户端然后,前端持久化到 Cookie
或者存储在本地(web前端存储在 localstorage 移动前端持久化到配置文件或数据库里,每次请求可以携带在 http header 字段里面)
在服务器一般存于数据库中
修改上面的登录逻辑,使用 DES 对 用户ID 和登录时间加密,生成 Token,放入 Cookie 中
今天就学到这里,下午请半天假
明天计划的事情:
1、学习SpringMVC 拦截器,并对请求做统一登录校验
2、Java 常见的加密算法学习
遇到的问题:
暂无
收获:
学习了 Cookie Session Token相关的知识
评论