1.前端登录发起请求
(1).安装axio
//导入axios
import axios from 'axios';
axios.defaults.baseURL="http://127.0.0.1:8081/WebBack/";//问题1
Vue.prototype.$http=axios;
(2).组装请求数据
使用form,将数据组装
2.后端接受请求
此时前端已经成功将数据传给后端
导入代码,使后端可以接收到数据
//将json对象序列化为键=值&键=值
function jsonToString(jsonobj){
console.log(jsonobj)
var str = "";
for(var s in jsonobj){
str+=s+"="+jsonobj[s]+"&";
}
return str.substring(0,str.length-1);
}
3.连接数据库
(1).创建一个数据库,创建一个管理员表(SQL)
(2).搭建jbdc连接数据库
4.后端响应
接收到Dao返回的查询数据
public class LoginDao {
public Admin login(String account,String password)throws ClassNotFoundException, SQLException {
Connection connection=null;
PreparedStatement ps =null;
//可以在finally运行
Admin admin=null;
try{
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/webback?servertimezone=Asia/Shamghai";
String uname="root";
String pwd="root";
connection= DriverManager.getConnection(url,uname,pwd);
ps=connection.prepareStatement("SELECT id,account FROM myadmin WHERE account=? AND PASSWORD=?");
ps.setObject(1,account);
ps.setObject(2,password);
ResultSet rs=ps.executeQuery();
while(rs.next()){//遍历
admin=new Admin();
admin.setId(rs.getInt("id"));
admin.setAccount(rs.getString("account"));
}
}finally {
if(connection!=null){
connection.close();//账号密码等有问题
}
if(ps!=null){
ps.close();
}
}
return admin;
}
}
进行数据封装,创建了commoResult类 code data message
public class CommoResult {
private int code;//状态码,404是前端响应码
private Object data;//数据 对象 集合等
private String message;
//构造方法
public CommoResult(int code, Object data, String message) {
this.code = code;
this.data = data;
this.message = message;
}
public CommoResult(int code, String message) {
this.code = code;
this.message = message;
}
}
进行逻辑判断
public Admin login(String account,String password)throws ClassNotFoundException, SQLException {
Connection connection=null;
PreparedStatement ps =null;
//可以在finally运行
Admin admin=null;
try{
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/webback?servertimezone=Asia/Shamghai";
String uname="root";
String pwd="root";
connection= DriverManager.getConnection(url,uname,pwd);
ps=connection.prepareStatement("SELECT id,account FROM myadmin WHERE account=? AND PASSWORD=?");
ps.setObject(1,account);
ps.setObject(2,password);
ResultSet rs=ps.executeQuery();
while(rs.next()){//遍历
admin=new Admin();
admin.setId(rs.getInt("id"));
admin.setAccount(rs.getString("account"));
}
}finally {
if(connection!=null){
connection.close();//账号密码等有问题
}
if(ps!=null){
ps.close();
}
}
return admin;
}
异常处理
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String account=req.getParameter("account");
String password=req.getParameter("password");
System.out.println(account+":"+password);
PrintWriter printWriter= resp.getWriter();//输出流的对象
resp.setContentType("text/html;charset=utf-8");
//设置响应编码
CommoResult commoResult=null;//后端数据封装的一个公共类
try {
LoginDao loginDao=new LoginDao();
Admin admin=loginDao.login(account,password);
if(admin!=null){
commoResult=new CommoResult(200,admin,"success");
}else{
commoResult=new CommoResult(201,admin,"defeat");
}
}catch (Exception e){
e.printStackTrace();//打印错误原因
commoResult=new CommoResult(500,"busy");
}
ObjectMapper objectMapper=new ObjectMapper();
String json=objectMapper.writeValueAsString(commoResult);//数据都在commReasult中
printWriter.print(json);
}
报错500()原因:未给CommoResult类中写入getter和setter方法
账号密码成功登录时检查界面
账号密码不匹配登陆失败界面
5.前端处理
(1).接受后端相应的数据
(2).前端路由跳转(登陆成功后跳转到管理界面)
(3).前端存储用户信息
网页关闭后用户信息也会自动消失
(4).在main组件中显示用户账号
export default{
data(){
return{
account:""
}
},
methods:{
},
mounted() {
this.account=sessionStorage.getItem("account");
}
}
再将登陆后的界面中显示用户信息的div改为{{account}}
Web会话跟踪
● 什么是会话
从一个客户打开浏览器并连接到服务器开始,到客户关闭浏览器离开这
个服务器结束,被称为一个会话。
● 为什么要会话跟踪
主要原因是因为 HTTP 请求是无状态的;只有当用户发出请求时,服
务器才会做出响应,客户端与服务端之间的联系是离散的、非连续的;如
果用户想在同一个网站的多个页面之间转换时,无法确定是否是同一个用
户;对会话进行跟踪就是为了解决这样的问题。
会话跟踪是Web程序中常用的技术,用来跟踪用户的整个会话过程。
给客户端们颁发一个通行证,每人一个,无论谁访问都必须携带自己通
行证。这样服务器就能从通行证上确认客户身份了。
![](https://i-blog.csdnimg.cn/blog_migrate/953aedf0d985ba228b96673825c61463.png)
token
● token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,
服务器生成一个token便将此token返回给客户端,以后客户端只需带上这个token前来
请求数据即可。token保存在客户端,并且进行了加密,保证了数据的安全性.
● 目的:token的目的是为了减轻服务器的压力,使服务器更加健壮
6.在前端验证用户是否登录
7.web会话跟踪
http是无状态的,登陆完成后,客户端就与服务器断开连接,之后再像后端发送请求,就不知道是哪个用户发送的请求
使用会话跟踪:
- 登陆,像后端发送账号和密码
- 后端与数据库连接验证账号密码(之前已完成)
- 如果账号和密码正确,在后端就会生成一个token(令牌 ,唯一),把token响应给前端
- 在前端存储token
- 之后的每一次请求都会将token携带周像后端发送
- 后端的java对请求中的token进行解析和验证
JWT
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一
种基于 JSON 的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于
通信双方之间以 JSON 对象的形式安全的传递信息。因为数字签名的存在,这些
信息是可信的,JWT 可以使用 HMAC 算法或者是 RSA 的公私秘钥对进行签名。
优点
1.简洁(Compact): 可以通过 URL,POST 参数或者在 HTTP header 发送,因为数
据量小,传输速度也很快
2.自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次
查询数据库
3.因为 Token 是以 JSON 加密的形式保存在客户端的,所以 JWT 是跨语言的,原
则上任何 web 形式都支持。
4.不需要在服务端保存会话信息,特别适用于分布式微服务。
token密钥添加成功后登陆检查就会出现以下界面
axios拦截(写在main.js中)
//请求拦截,没法送一次http请求,她都会执行此拦截器一次
axios.interceptors.request.use(config =>{
//为请求头对象,添加 Token 验证的 token 字段
//不用每次加token
config.headers.adminToken = window.sessionStorage.getItem('adminToken');
return config;
})
此时已将admin token放入请求头中了 (此时前端问题已解决)
将后端的admin token验证放入过滤器中
public class AdminTokenFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//接收请求头中的adminToken
HttpServletRequest request=(HttpServletRequest)servletRequest;//向下转型,强制类型转换
String adminToken=request.getHeader("adminToken");
boolean verify=JWTUtil.verify(adminToken);
if (verify){
filterChain.doFilter(servletRequest,servletResponse);
//继续向后执行
}else {
servletResponse.setContentType("text/html;charset=utf-8");
PrintWriter printWriter=servletResponse.getWriter();
CommoResult commoResult=new CommoResult(401,"token验证失败,请重新登陆");
ObjectMapper objectMapper=new ObjectMapper();
String json=objectMapper.writeValueAsString(commoResult);
printWriter.print(json);
//将commresult转化为json,在打印出来
}
}
}
在web.xml中配置过滤器
<!-- 配置验证token-->
<filter>
<filter-name>adminTokenFilter</filter-name>
<filter-class>WebBack.Servelet.Filter.AdminTokenFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>adminTokenFilter</filter-name>
<url-pattern>/*</url-pattern>
<!-- 注意此时不能写*,否则登陆时会没有反应,第一次登陆时没有生成token-->
</filter-mapping>
点击测试后出现如下截图,说明已经经过了token过滤器
token验证成功