• JWT ajax java spingmvc 简洁教程


    1、添加依赖

      

            <dependency>
                  <groupId>io.jsonwebtoken</groupId>
                  <artifactId>jjwt</artifactId>
                  <version>0.6.0</version>
            </dependency>
            <dependency>
                <groupId>com.thetransactioncompany</groupId>
                <artifactId>cors-filter</artifactId>
                <version>2.5</version>
            </dependency>
             <dependency>
                <groupId>com.thetransactioncompany</groupId>
                <artifactId>java-property-utils</artifactId>
                <version>1.9.1</version>
            </dependency>

    2、登录 及登录后获取菜单信息

    package com.fescotech.national.common.web.jwt;
    
    import io.jsonwebtoken.Claims;
    
    import java.io.IOException;
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.fescotech.apps.national.manager.web.api.base.IBaseUserApi;
    import com.fescotech.apps.national.manager.web.dto.basic.user.BaseUser;
    import com.fescotech.national.common.web.dto.Menu;
    import com.fescotech.national.common.web.dto.Res;
    import com.fescotech.national.common.web.menu.IMenuProvider;
    
    
    
    @Controller
    public class JWTLoginController {
        @Autowired
        private IMenuProvider menuProvider;
        @Autowired
        private IBaseUserApi iBaseUserApi;
    
        /**
         * 登录
         */
        @ResponseBody
        @RequestMapping(value = "/jwt/login", method = RequestMethod.POST)
        public Res login(String username, String password)throws IOException {       
            //登录成功后,查询用户信息
            BaseUser buS = new BaseUser();
            buS.setUserName(username);
            BaseUser user = iBaseUserApi.queryUserByLoginName(buS);
            //账号不存在或密码错误
            if(user == null || !password.equals(user.getUserPwd())) {
               return Res.error("0", "账号或密码不正确");
            }
            //账号不存在或密码错误
            if(user.getUserType()!=3) {
               return Res.error("0", "非超级管理员不可登录后台");
            }
            //登录成功返回 客户端 token
            String userToken = TokenUtil.getJWTString(user);
            LoginOkData ld = new LoginOkData();
            ld.setToken(userToken);
            return Res.ok("1", "登录成功", ld, 1);
        }
        /**
         * 加载用户权限菜单
         *
         */
        @ResponseBody
        @RequestMapping(value = "/jwt/getMenu", method = RequestMethod.POST)
        public Res getMenu(String token){
            //接收客户端token 进行验证
            Claims claims = TokenUtil.isValid(token, TokenUtil.key);
            if(null == claims){
               System.out.println("token 验证失败!");
               return Res.error("-1", "token失效");
            }
            //验证通过 获取用户信息
            String userId = (String)claims.get("userId");
            List<Menu> menuList = menuProvider.getUserMenu(userId, null);
            return Res.ok("1", "菜单请求成功", menuList, 1);
           
        }
    }

    3、生成及验证 token 

    package com.fescotech.national.common.web.jwt;
    
    import java.util.Calendar;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    
    import com.fescotech.apps.national.manager.web.dto.basic.user.BaseUser;
    
    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    
    public class TokenUtil {
        public static String key = "fescoTecth";
        /**
         * 生成token 并返回
         *
         */
        public static String getJWTString(BaseUser user){
            Map<String,Object> claims = new  HashMap<String,Object>();
            claims.put("userName", user.getUserName());
            claims.put("userId", user.getUserId());
            Date expires = new Date();
            Calendar c = Calendar.getInstance();
            c.add(Calendar.SECOND, 30);
            expires = c.getTime();
            SignatureAlgorithm signatureAlgorithm =SignatureAlgorithm.HS256;
            String jwtString = Jwts.builder()
                    .setIssuer("Jersey-Security-Basic")
                    .setSubject(user.getUserName())
                    .setAudience("user")
                    .setExpiration(expires)
                    .setClaims(claims)
                    .setIssuedAt(new Date())
                    .setId(user.getUserId())
                    .signWith(signatureAlgorithm,key)
                    .compact();
            return jwtString;
        }
        
        /**
         * 验证token 是否有效
         *
         */
        public static Claims isValid(String token, String key) {
            try {
                Claims claims = (Claims)Jwts.parser().setSigningKey(key).parseClaimsJws(token.trim()).getBody();
                return claims;
            } catch (Exception e) {
                return null;
            }
        }
    }

    4、拦截器 添加允许跨域访问

      

    package com.fescotech.national.common.web.filter;
    import java.io.IOException;
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.web.filter.OncePerRequestFilter;
    /**
     * 拦截器,允许跨域访问
     * @author feiye
     *
     */
    public class CorsFilter extends OncePerRequestFilter {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            response.addHeader("Access-Control-Allow-Origin", "*");      //为安全起见,可配置允许访问的请求方地址。这里配置成*号,是允许所有访问。
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");        //为安全起见,也可配置成只允许POST请求
            response.addHeader("Access-Control-Allow-Headers", "Content-Type,auth_token");      //这里要注意,auth_token是我自定义的请求头当中带的token,在这里必须添加,否则你永远获取不到。
            response.addHeader("Access-Control-Max-Age", "60");//30 min
            filterChain.doFilter(request, response);
        }
    }

    5、web.xml 添加拦截器配置

      

      <filter>
        <filter-name>cros</filter-name>
        <filter-class>com.fescotech.national.common.web.filter.CorsFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>cros</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>

    6、前端ajax 请求 

      

    logins:方法 提交用户名密码 进行登录,登录成功后,获得 token放入全局变量
    getMenu:方法,提交 token 服务器进行验证,通过后,获取对应的用户信息,根据用户信息获取对应的权限菜单信息并返回,完成一次数据请求。
    登录成功后,每次请求都要带上 token 服务器验证通过后,方可接收请求,否则不处理客户端请求

      

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <script src="js/jquery.min.js"></script>
     <style>
     #mains{width:100%}
         #imgCode {width: 100px; border:1px solid green;}
     </style>
    </head>
    <body>
    <div id="mains">
    <input type="input" id="codes" > <br/>
    <img id="imgCode"  src="http://localhost:61000/nmweb/captcha.jpg"/>
    <br/>
    <input type="button" onclick="logins()" width="100px" value="登录">
    <input type="button" onclick="getMenu()" width="100px" value="菜单">
    </div>
    <script type="text/javascript">
    var token = "";
    function logins(){
    var code = $("#codes").val();
    var preLocalUrl = "http:/localhost:8080/nbmweb";
    var url = preLocalUrl+"/jwt/login";
        $.ajax({
             type: 'POST',
              url: url,
              data: "username=admin&password=admin&captcha="+code,
             
              success:function(msg){
                  console.log(msg);
                  var res = jQuery.parseJSON(msg);
                  var data = res.data;
                 // var ldData = jQuery.parseJSON(data);            
                  token = data.token;
              },
              error:function(errors){
                  console.log(errors);
              }
        })
    }
    function getMenu(){
        var url = "http://localhost:8080/nbmweb/jwt/getMenu";
        console.log("url-->"+url);
        console.log("token-->"+token);
        $.ajax({
             type: 'POST',
              url: url,
              data:"token="+token,
              success:function(msg){
                  console.log(msg);                  
              },
              error:function(errors){
                  console.log(errors);
              }
    })
    }
    </script>
    </body>
    </html>

    7、以上demo 仅做测试,没有理论讲解比较随心,实际使用中,按需优化。

      关于,文件上传,获取验证码,token 的刷新和注销,请待下回分解

      推荐参考:https://bbs.csdn.net/topics/392006333

  • 相关阅读:
    hdu 1541 Stars(经典BIT)
    CODE[VS] 1082 线段树练习3(区间修改+区间查询)
    Luogu P3368 【模板】树状数组 2(区间修改,单点查询)
    牛客小白月赛5-I-区间(差分求前缀和+一次暴力统计)
    牛客小白月赛5-J-时间(time) (简单模拟)
    牛客小白月赛5-D-阶乘(求n内每个数的阶乘相乘后尾数为0的个数)
    CF1110C Meaningless Operations(构造题)
    洛谷4859 BZOJ3622 已经没什么好害怕的了(DP,二项式反演)
    二项式反演学习笔记
    UVAlive-7040 color(组合数学,二项式反演)
  • 原文地址:https://www.cnblogs.com/feiye512/p/8717691.html
Copyright © 2020-2023  润新知