赞
踩
首先使用axios来发送, 因为原生态的ajax代码繁琐
npm install axios
这里就引入axios.js的组件来使用axios发送请求
发送get请求
- this.$http.get("http://localhost:8080/webBack_5.14/login?account=jwq&password=111").then(function(resp){
- //业务逻辑代码
- })
发送post请求
- this.$http.get("http://localhost:8080/webBack_5.14/login?account=jwq&password=111").then(function(resp){
- //业务逻辑代码
- })
由于json是一种轻量级的数据格式, 所以前后端传输数据时候, 经常用json格式来传输
在前端可以写一个方法来转化数据格式:
请求里做参数转json格式,直接发送json的请求
如果仅仅是通过登录框验证密码还是不够安全, 还可以通过URL地址来直接进行访问, 就会跳过登录的页面。
所以要将一个验证信息放到浏览器里—>(sessionStorage)
他是浏览器里可以存储数据的容器, 在关闭浏览器时就会清除
因此将用户信息存储到sessionStorage(会话储存) 里 , 在进入具体操作的网页网页时候可以先进行判断, 如果有会话存储里有账号, 那么就可以进行访问, 不然那就回到登录的页面, 这样验证就更加符合需求,
而且此时的sessionStorage还可以将登录人的信息, 账号放到页面上显示, 就好像京东这些购物软件, 将用户人的登录信息展示到我的这一页面,就可以将操作人的信息放到sessionStorage里面, 随后在哪个页面想要获取渲染在前端时, 就可以随时获取, 非常方便
登陆账号的id会显示到右上角
<1>放入account
<2>添加web会话跟踪技术
这是在router对象的那个index.js文件里配置
提高安全性(session不安全), 使用token来验证
session缺点
浏览器里的数据时可以随时改的, 就会让一些不法分子走漏洞, 所以在前端验证并不是万全之策
用户认证之后,服务端做认证记录,如果认证的记录被保存在内存
中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。
因此要引入另一种安全的高效的验证操作, token 验证方式.
首先在登录成功之后, 要在后端生成token, 再将token连随响应数据一并发送给前端, 前端得到token之后, 在接下来的每一次发送请求都会将token携带到请求里, 到后端来验证token是否正确, 正确就继续执行操作, 不正确就要返回 token不对的异常信息.
生成token
首先导入包
由JWT的方式生成token 点击去看JWT
- package com.ffyc.webback.util;
-
- import com.auth0.jwt.JWT;
- import com.auth0.jwt.JWTVerifier;
- import com.auth0.jwt.algorithms.Algorithm;
- import com.auth0.jwt.interfaces.DecodedJWT;
- import com.ffyc.webback.dao.Admin;
-
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
-
- /**
- * JWT工具类
- */
- public class JWTUtil {
-
- /**
- * 根据用户id,账号生成token
- * @param
- * @return
- */
- public static String getToken(Admin admin) {
- String token = "";
- try {
- //过期时间 为1970.1.1 0:0:0 至 过期时间 当前的毫秒值 + 有效时间
- Date expireDate = new Date(new Date().getTime() + 10*1000);
- //秘钥及加密算法
- Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
- //设置头部信息
- Map<String,Object> header = new HashMap<>();
- header.put("typ","JWT");
- header.put("alg","HS256");
- //携带id,账号信息,生成签名
- token = JWT.create()
- .withHeader(header)
- .withClaim("id",admin.getId())
- .withClaim("account",admin.getAccount())
- .withExpiresAt(expireDate)
- .sign(algorithm);
- }catch (Exception e){
- e.printStackTrace();
- return null;
- }
- return token;
- }
-
- /**
- * 验证token是否有效
- * @param token
- * @return
- */
- public static boolean verify(String token){
- try {
- //验签
- Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
- JWTVerifier verifier = JWT.require(algorithm).build();
- DecodedJWT jwt = verifier.verify(token);
- return true;
- } catch (Exception e) {//当传过来的token如果有问题,抛出异常
- return false;
- }
- }
-
- /**
- * 获得token 中playload部分数据,按需使用
- * @param token
- * @return
- */
- public static DecodedJWT getTokenInfo(String token){
- return JWT.require(Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE")).build().verify(token);
- }
-
- }

将token信息封装到admin对象里, 一并返回前端
package com.ffyc.webback.dao; public class Admin { private int id; private String password; private String account; private String token; public String getToken() { return token; } public void setToken(String token) { this.token = token; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } }
前端将信息放入浏览器的会话存储里
请求发送时,后端验证token
<1>配置过滤器 (除了登录都要走这个过滤器)
我们可以通过给走这个过滤器的请求添加一层级的路径, 具体如下图
这样就可以区分经过验证token过滤器与不验证token过滤器的请求了, 不验证就直接写请求地址, 验证就加上一层级的/token.
这是在每次请求时,将token放在请求的请求头区域里, 到后端浏览器调用
响应拦截器
在前端处理后端响应回来的状态码时, 每一个组件对相同部分状态码总是同一个业务流程, 如: 500 状态码时候, 就会弹出服务器异常的信息, 那这样会繁琐很多, 使得代码冗余。
在每次接收响应时, 可以根据状态码来做统一给用户做出响应结果, 可以将那些状态码放入响应拦截器里
后端结构: 如下
<1.>登陆账号判断
package com.ffyc.webback.dao; import java.sql.*; public class LoginDao{ public Admin login(String account, String password) throws ClassNotFoundException, SQLException { Connection connection = null; PreparedStatement ps =null; Admin admin= null; try{ Class.forName("com.mysql.cj.jdbc.Driver");//动态加载Driver String url = "jdbc:mysql://127.0.0.1:3306/webdb?serverTimezone=Asia/Shanghai"; String uname = "root"; String pwd = "root"; connection = DriverManager.getConnection(url,uname,pwd); ps = connection.prepareStatement("SELECT id,account FROM admins 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; } }
<2>业务处理层
public class LoginServlet extends HttpServlet { @Override public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException { String account = req.getParameter("account"); String password = req.getParameter("password"); CommonRes commonRes = null; try{ LoginDao loginDao = new LoginDao(); Admin admin = loginDao.checkAccount(account, password); System.out.println(admin); if (admin!=null){ //生成token String token = JWTUtil.token(admin); admin.setToken(token); commonRes = new CommonRes(200,admin,"登录成功"); }else{ commonRes = new CommonRes(201,"账号或密码错误"); } }catch(Exception e){ e.printStackTrace(); commonRes = new CommonRes(500,"服务器异常"); } //将common结果转化成jason格式返回 resp.setContentType("text/html;charset=UTF-8"); Writer writer = resp.getWriter(); ObjectMapper mapper = new ObjectMapper(); String jsonstr = mapper.writeValueAsString(commonRes); writer.write(jsonstr); }
所以在获取参数之前,要对请求 设置编码
request.setContetnType("text/html;charset=utf-8");, 在请求头设置编码
同理, 后端服务器给前端做出响应的时候也应该设置响应编码, 否则会出现前端接收响应时, 响应的是乱码问题
response.setContetnType("text/html;charset=utf-8")
跨域是指从一个域名的网页去请求另一个域名的资源。比如从www.baidu.com 页面去请求 www.google.com 的资源。但是一般情况下不能这么做,它是由浏览器的同源策略造成
由此我们可以写过一个过滤器来实现
package com.ffyc.webback.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CorsFilter implements Filter { public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) servletResponse; HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; //允许携带Cookie时不能设置为* 否则前端报错 httpResponse.setHeader("Access-Control-Allow-Origin", httpRequest.getHeader("origin"));//允许所有请求跨域 httpResponse.setHeader("Access-Control-Allow-Methods", "*");//允许跨域的请求方法GET, POST, HEAD 等 httpResponse.setHeader("Access-Control-Allow-Headers", "*");//允许跨域的请求头 httpResponse.setHeader("Access-Control-Allow-Credentials", "true");//是否携带cookie filterChain.doFilter(servletRequest, servletResponse); } }
然后在web.xml里面配置过滤器
由于每次对后端结果进行返回时候,只能一个一个返回, 所以此时可以封装一个返回的结果集
commonRes
public class CommonResult { private int code; private Object data; private String message; public CommonResult(int code, Object data, String message) { this.code = code; this.data = data; this.message = message; } public CommonResult(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
<1>首先要导入jar包
<2>在使用mapper对象里的writeValuesAsString()对响应结果进行json格式的处理
- Writer writer = resp.getWriter();
- ObjectMapper mapper = new ObjectMapper();
- //commonRes这是上面说的返回结果集对象,放入mapper对象的
- //方法里,转json格式
- String jsonstr = mapper.writeValueAsString(commonRes);
- writer.write(jsonstr);
<3>json响应结果查看
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。