*Web会话跟踪技术

前言

在我们做项目时,每次浏览器向后端发送请求时,需要让后端知道这是哪个用户在操作的,它是基于token会话跟踪技术,这个功能的实现就是web会话跟踪技术

会话跟踪技术的实现

1.token的生成

会话跟踪技术中,在登录成功后,在后端生成一个token(字符串),可携带用户信息,加密
①JWT是生成token的方式
优点:简洁
可以携带用户信息
可以加密
不需要在服务器端存储,节省空间
如何生成token?
❶导入jwt组件的jar
❷导入JWTUtil类
示例如下:

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JWTUtil {

    /**
     * jwt 生成 token
     * @param id
     * @param account * @return
     */
    public static String token (Integer id, String account){
        String token = "";
        try {
             //过期时间 为 1970.1.1 0:0:0 至 过期时间 当前的毫秒值 + 有效时间
            Date expireDate = new Date(new Date().getTime() +60*60*24*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",id)//用户id
                    .withClaim("account",account)//用户账号
                    .withExpiresAt(expireDate)//过期时间
                    .sign(algorithm);
        }catch (Exception e){
            e.printStackTrace(); return null;
        }
        return token;
    }

    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);
    }
}

2.token进行响应

①当token生成之后,将其放入到admin用户数据中并且响应给前端
示例如下

 //登录成功,生成token,token中携带用户信息
                //在后端将token字符串添加到admin中,并且响应给前端
                String token = JWTUtil.token(admin.getId(), admin.getAccount());
                admin.setToken(token);

②在浏览器中将token字符串进行存储

//sessionStorage是浏览器提供的一个会话级别的存储空间,浏览器关闭后立刻消失
							
							sessionStorage.setItem("token",resp.data.data.token);

当重新进入一个组件时,token每次与后端交互,将数据放在请求头中, 然而每次发送都比较麻烦,因此可以在main.js中配置一个axios请求拦截器,这样就不用每次都发送,减少代码冗余
示例如下:

//axios 请求拦截
axios.interceptors.request.use(config =>{
//向请求头中添加一个自定义的请求头,只需要定义一次即可
 config.headers.token = sessionStorage.getItem('token');
    return config;	
    })

3.接收请求头中的数据对token进行解析验证

①当token传到后端时,每次都需要进行验证,比较麻烦,因此我们可以将验证写进一个过滤器中,因此再进入目标Servlet之前,经过过滤器,验证token
示例如下:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ffyc.webBack.util.CommonResult;
import com.ffyc.webBack.util.JWTUtil;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class TokenFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest  req =(HttpServletRequest)servletRequest;
        String token  = req.getHeader("token");//获取请求头中的数据
        boolean res =  JWTUtil.verify(token);//验证token
        if(res){
            //token 没有问题,让请求继续向下执行,由目标的selvet进行响应
            filterChain.doFilter(servletRequest,servletResponse);

        }else{
            //token验证失败
            HttpServletResponse response = (HttpServletResponse)servletResponse;
            response.setHeader("Content-Type", "text/html;charset=utf-8");//设置响应内容的编码
            PrintWriter pt = response.getWriter();

            CommonResult commonResult=new CommonResult(202,res, "验证token失败");
            ObjectMapper objectMapper = new ObjectMapper();
            String json = objectMapper.writeValueAsString(commonResult);
            pt.print(json);
        }

    }
}

 <!--配置token过滤器-->
    <filter>
        <filter-name>TokenFilter</filter-name>
        <filter-class>com.ffyc.webBack.filter.TokenFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>TokenFilter</filter-name>
        <url-pattern>/admin/*</url-pattern><!--因为token是在登录成功之后进行生成,因此在配置地址时,要跳过登录地址-->
    </filter-mapping>


②当验证token成功后,进行解析
示例如下:

public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.setHeader("Content-Type", "text/html;charset=utf-8");
        PrintWriter pt = resp.getWriter();


        String token = req.getHeader("token");//获取token
        DecodedJWT tokenInfo = JWTUtil.getTokenInfo(token);//解析token
        Integer id = tokenInfo.getClaim("id").asInt();//取出token的id
        String account = tokenInfo.getClaim("account").asString();//取出token的account

        System.out.println("测试请求"+id+":"+account);

        CommonResult commonResult = new CommonResult(200, null, "测试成功");
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(commonResult);
        pt.print(json);
    }


}

③将token验证及解析内容响应到前端(知道是哪个用户操作的)

test() {
				//向后端携带token
				this.$http.get("/admin/test").then((resp) => {
					if (resp.data.code == 200) {
						alert("测试成功");
					}
				})
			}

④token有可能过期或者更改,那么每个测试或组件都需要写出错情况下的代码,因此我们可以在main.js中配置一个响应拦截器,如果出现token验证失败,则直接进行拦截,减少代码重复性
示例如下:

// 添加响应拦截器
axios.interceptors.response.use((resp) =>{
	//正常响应拦截
    if(resp.data.code==500){
        ElementUI.Message({message:resp.data.message,type:"error"})
    }
    if(resp.data.code==202){
		sessionStorage.clear();//token验证失败,认为登录失效,可以清空存储信息,让其重新登录
        router.replace("/login");
    }
        return resp;
    });

总结

  • 以上工作做完之后,使用token(令牌)进行对用户信息的监测和验证,才可以说前后端交互方面的信息处理才比较安全,这样才会使用户操作的更加安全可靠,当然也是前后端交互时必不可少的事情
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值