Java Token登录验证 生成解析Token

借鉴参考

Java Token登录验证 使用jjwt生成和解析JWT
java基于token验证之登陆验证

什么是Token?

我的理解来说 token就是你访问服务器的口令,只要token合法,正确,你就能获取到后端数据

当用户第一次登陆后,用户名密码验证成功后,服务器会生成一个token,把token返回到客户端,一般token都是储存在浏览器的localStorage 或 cookies中,存在localStorage的token需要通过js,将token添加到http请求头中,下次再访问服务器,就不需要用户名密码了,只要带上token,服务器验证token的合法性后,就能访问后端资源了。是不是觉的很方便

添加依赖

我的项目是用gradle构建的,maven添加依赖可以百度一下
implementation (“io.jsonwebtoken:jjwt:0.9.0”)
implementation (“com.auth0:java-jwt:3.4.0”)

我前端是vue.js 用了element ui 三方库,servlet,mybatis

参考了链接

public class TokenSign {
    /**
     * @author
     * 设置过期时间 1小时钟 为了方便测试
     * 设置Token密匙 最好长一点
     */
    private static final long EXPIRE_TIME= 60 * 60 * 1000;
    private static final String TOKEN_SECRET="Token";
    /**
     * 产生token
     * @param useName
     * @param userId
     * @return
     */
    public static String Sign(String useName , long userId){
        try{
        	//这里将useName 和 userId 存入了Token,在下面的解析中,也会有解析的方法可以获取到Token里面的数据
            //Token过期的时间 
            Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME);
            System.out.println("date"+date);
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);

            //设置头部信息
            Map<String,Object> header = new HashMap<>();
            header.put("typ","JWT");
            header.put("alg","HS256");

            //附带username和userid信息,存储到token中,生成签名
            return JWT.create()
                    .withHeader(header)

                    //存储自己想要留存给客户端浏览器的内容
                    .withClaim("userName",useName)
                    .withClaim("userId",userId)
                    .withExpiresAt(date)
                    .sign(algorithm);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * token校验是否正确
     * @param token
     * @return
     */

    public static boolean verify(String token){
        try{
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);

            JWTVerifier verifier = JWT.require(algorithm).build();

            DecodedJWT decodedJWT = verifier.verify(token);

            return true;

        }catch (Exception e){
            System.out.println("Token超时,需要重新登录");
        }

        return false;
    }

    /**
     * 获取token中信息 userName
     * @param token
     * @return
     */

    public static String getUsername(String token){
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userName").asString();

        }catch (JWTDecodeException e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取token中信息 userId
     * @param token
     * @return
     */

    public static Long getUserId(String token){
        try{
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userId").asLong();
        }catch (JWTDecodeException e){
            e.printStackTrace();
        }
        return null;
    }

}

前端收到的数据
Response中的Token
储存到localStorage中的token
储存到localStorage中的token

请求头添加Token

在main.js 中添加拦截器,添加请求头在这里插入图片描述

axios.interceptors.request.use(config => {
	// 为请求头添加Authorization字段为服务端返回的token
	config.headers.Authorization = localStorage.getItem('token')
	return config
  })

这样的话请求头添加了token
Java Token登录验证 生成解析Token_第1张图片

过滤器

@WebFilter注解详情
这里的urlPatterns填路径
如果我的 @WebServlet("/Jwt/JwtListTest") 是这样的 WebServlet就能过滤下掉
如果我的 @WebServlet("/sadasda/JwtListTest") 是这样的 WebServlet就不能过滤 TheInterceptor就不会执行

@WebFilter(filterName = "TheInterceptor",urlPatterns = {"/jwt/*"})
public class TheInterceptor implements Filter {
    //初始化
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter初始化");
    }


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("doFilter");
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");
        ObjectNode objectNode=new ObjectNode(JsonNodeFactory.instance); //初始化json对象
        PrintWriter out = response.getWriter();

        String url = req.getServletPath();

		//获取请求头Authorization字段的数据
        String token = req.getHeader("Authorization");

        boolean result = false;
        /**
         * 1001 token不存在,先登录
         * 1002 token存在,但是token不合法
         *
         * 2000 用户名或密码错误
         * 2999 登陆成功
         * 2998 注销登录成功
         * 2997 注销登录失败
         *
         * 3000 用户注册失败
         * 3001 用户名重复
         * 3999 用户注册成功
         *
         * 3002 用户信息更新成功
         * 3998 用户信息更新失败
         */
        //如果url 复合 这些,直接放行,不用验证token
        if (
                "/jwt/JwtLogin".equalsIgnoreCase(url) ||
                        "/jwt/JwtRegister".equalsIgnoreCase(url) ||
                            "/jwt/JwtOrderDetail".equalsIgnoreCase(url) ||
                                    "/Jwt/JwtListTest".equalsIgnoreCase(url)){
            System.out.println("if语句执行了");
            chain.doFilter(request, response);//这是放行的语句
        }else {
            /**
             * 如果不是,登录界面,注销界面,注册界面 则执行以下语句
             * 如果 要去商品界面,购物车界面等需要,登录状态的界面,
             * 如果token==null 说明 没有登录,数据返回前端,让前端进行跳转到登录界面登录
             * 如果token !== null 先进行token合法性的验证
             * 如果token 不合法,数据返回前端,让前端进行跳转到登录界面登录,合法则让请求,去到相应界面
             */
            if (token == null){  //如果token存在 则执行放行
                System.out.println("token不存在");
                objectNode.put("status",1001);
                out.println(objectNode);
                out.close();
            }else {
                //如果是不空,说明登陆过,先判断token合法性(也包括了对token时效性的判断)
                result = TokenSign.verify(token);
                if (result){
                    System.out.println("token合法");
                    try {
                        chain.doFilter(request, response);
                    }catch (Exception e){
                        System.out.println("chain.doFilter报错");
                        e.printStackTrace();
                    }
                    System.out.println("token合法1");
                }else {
                    System.out.println("token不合法");
                    objectNode.put("status",1002);
                    out.println(objectNode);
                    out.close();
                }

            }
        }

    }

    @Override
    public void destroy() {
        System.out.println("Filter摧毁");
    }
}

这篇博客借鉴参考很多,主要为了是加深自己的记忆,希望各位大牛不要见笑,如果有错误请告知

基于Token的WEB后台认证机制
Java实现基于token认证

你可能感兴趣的:(Java Token登录验证 生成解析Token)