做JavaWeb开发,难免会遇到登录系统保持登录状态的问题?比如说我登录过后关闭浏览器,下次再访问相同的网站,默认会显示已登录状态,一段时间内就不必再重新登录了;再比如站在后台接口设计的角度去考虑,用户登录后,做了一系列的用户操作接口,那么这些接口不可能都带上一个userid的字段吧,这样不仅开发麻烦,而且容易被黑客攻击。那么如何解决这些问题呢?那就是通过代理服务对客户端请求的拦截来实现,经过验证后才开始执行业务逻辑。
如何搭建代理服务的过程,这里就不详细介绍了,我们以实现保持登录状态为例,实现原理大概是这样子的:
1.客户端请求后台登录接口。
2.后台验证通过后,将用户的登录状态保存至cookie并写入客户端。
3.客户端再次登录网站,请求login接口时,后台直接从客户端获取到该用户写入cookie的登录状态。
4.通过对该状态的验证,确认用户是否需要再次登录。
5.如cookie过期,则跳转至登录页;如未过期,则直接显示为已登录状态。
这里前端js用ajax请求即可,如请求一个url地址:
我们要注意一点,在请求成功后的Response Headers中,有Set-Cookie一项,设置一个key为java,value为myJavaData的Map值,这个是重点,有这个值客户端就会自动把这个Map值设为cookie值,这就是我们所说的登录状态loginState,如下图所示:
那么这个Set-Cookie一项数据怎么来呢?是通过Java后台设置的,源码如下:
// 设置格式
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST");
response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type");
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
// 创建Cookie
Cookie cookie = new Cookie("java", "myJavaData");
// 有效期,秒为单位
cookie.setMaxAge(3600);
// 设置cookie
response.addCookie(cookie);
response.getWriter().print("cookie创建成功");
这样一来,就实现了在后台服务端为客户端设置cookie的功能,用户在下次请求相同域的接口时,java后台只需
// 获取客户端cookie
request.setCharacterEncoding("utf-8");
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
System.out.println(c.getName() + "--->" + c.getValue());
}
}
即可获取客户端的登录状态,从而做出响应操作。(注意)此处的cookie值无需客户端专门带入,会随请求自动传输到后台。上例中的setMaxAge即为登录状态的有效期设置点。
还有一种业务状态是希望,用户只要关闭了浏览器,该登录状态就会清除,下次打开浏览器必须重新登录,如CSDN博客登录即使如此。这种情况我们可以使用session会话实现:java后台设置session代码
// 设置格式
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST");
response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type");
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
// 使用request对象的getSession()获取session,如果session不存在则创建一个
HttpSession session = request.getSession();
// 将数据存储到session中
session.setAttribute("java", "myJavaData");
// 获取session的Id
String sessionId = session.getId();
// 判断session是不是新创建的
if (session.isNew()) {
response.getWriter().print("session创建成功,session的id是:" + sessionId);
} else {
System.out.println(session.getAttribute("java")); // 值myJavaData
response.getWriter().print(
"服务器已经存在该session了,session的id是:" + sessionId);
}
当然,上面只是举了一些简单的例子,在实际应用中不可能只保存一个loginState这么简单,还会保存如OSS_COOKIES,使用token值验证等多种安全验证手段综合。以上实现都是在请求与页面同域的情况下,如果想要跨域实现,即客户端与后台不在同一个域名下,则通过JSONP实现。