• 利用jwt生成token,用于http请求身份验证


      前段时间在做移动端接口过程中,考虑到安全性,所有移动端发送请求(除了登录请求)过程中进行token有效验证。

       1.利用jwt生成token

       a.导入jwt相关包

      

            <!-- jwt -->
            <dependency>
                <groupId>com.nimbusds</groupId>
                <artifactId>nimbus-jose-jwt</artifactId>
                <version>4.23</version>
            </dependency>            

       b.编写生成token的工具类TokenUtils

      

    public class TokenUtils {
    
        private static final byte[] secret = "geiwodiangasfdjsikolkjikolkijswe".getBytes();
    
    
        //生成一个token
        public static String creatToken(String uid) throws JOSEException {
    
            Map<String,Object> payloadMap = new HashMap<>();
            payloadMap.put("uid", uid);
            //生成时间
            payloadMap.put("sta", new Date().getTime());
            //过期时间
            payloadMap.put("exp", new Date().getTime()+1000*60*60*24); //24小时token失效
            
            //先建立一个头部Header
            JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256);
    
            //建立一个载荷Payload
            Payload payload = new Payload(new JSONObject(payloadMap));
    
            //将头部和载荷结合在一起
            JWSObject jwsObject = new JWSObject(jwsHeader, payload);
    
            //建立一个密匙
    
            JWSSigner jwsSigner = new MACSigner(secret);
    
            //签名
            jwsObject.sign(jwsSigner);
    
            //生成token
            return jwsObject.serialize();
        }
        
    
        public static Map<String,Object> valid(String token) throws JOSEException, ParseException {
    
            JWSObject jwsObject = JWSObject.parse(token);
    
            //获取到载荷
            Payload payload=jwsObject.getPayload();
    
            //建立一个解锁密匙
            JWSVerifier jwsVerifier = new MACVerifier(secret);
    
            Map<String, Object> resultMap = new HashMap<>();
            //判断token
            if (jwsObject.verify(jwsVerifier)) {
                resultMap.put("Result", 0);
                //载荷的数据解析成json对象。
                JSONObject jsonObject = payload.toJSONObject();
                resultMap.put("data", jsonObject);
    
                //判断token是否过期
                if (jsonObject.containsKey("exp")) {
                    Long expTime = Long.valueOf(jsonObject.get("exp").toString());
                    Long nowTime = new Date().getTime();
                    //判断是否过期
                    if (nowTime > expTime) {
                        //已经过期
                        resultMap.clear();
                        resultMap.put("Result", 2);
                    }
                }
            }else {
                resultMap.put("Result", 1);
            }
            return resultMap;
    
        }
    }

      

        2.对于移动端所有请求进行过滤

        a.在web.xml中配置相关过滤器(对所有请求含有/app开头的进行拦截,除了/app/login)

        

       <filter>
            <filter-name>AppRequestFilter</filter-name>
            <filter-class>com.demo.common.filter.AppRequestFilter</filter-class>
            <init-param>
                <param-name>excludedRequests</param-name>
                <param-value>/app/login</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>AppRequestFilter</filter-name>
            <url-pattern>/app/*</url-pattern>
        </filter-mapping>

        b.编写AppRequestFilter类

        

    public class AppRequestFilter implements Filter{
        
        private String excludedRequests;
        private String[] excludedRequestArr;
        
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            excludedRequests = filterConfig.getInitParameter("excludedRequests");
            if(excludedRequests != null && excludedRequests.length() > 0){
                excludedRequestArr = excludedRequests.split(",");
            }
            return;
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            
            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse res = (HttpServletResponse) response;
            
            boolean isExcludedRequest = false;
            for (String requestStr : excludedRequestArr) {
                if (((HttpServletRequest) request).getServletPath().startsWith(requestStr)) {
                    isExcludedRequest = true;
                    break;
                }
            }
            if(isExcludedRequest){
                chain.doFilter(request, response);
            }else{
                String token = req.getHeader("app_token");
                if(StringUtil.isEmpty(token)){
                    responseError(res, "token为空!");
                    return;
                }else{
                    Map<String, Object> validMap;
                    try {
                        validMap = TokenUtils.valid(token);
                        int i = (int) validMap.get("Result");
                        if (i == 0) {
                            chain.doFilter(request, response);
                        } else if (i == 2) {
                            responseError(res, "token已经过期!");
                            return;
                        } else if(i == 1) {
                            responseError(res, "token无效!");
                            return;
                        }
                    } catch (JOSEException e) {
                        e.printStackTrace();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
                
            }
        }
        
        @SuppressWarnings("deprecation")
        private void responseError(HttpServletResponse res, String errorMsg) throws IOException {
            res.setHeader("content-type", "application/json;charset=UTF-8");
            OutputStream outputStream = res.getOutputStream();
            JsonResult msg = new JsonResult(false, errorMsg);
            IOUtils.write(JSONUtil.toJsonPrettyStr(msg), outputStream);
        }
    
        @Override
        public void destroy() {
            return;
        }
    }

        3.测试类编写

        

    @Controller
    @RequestMapping(value = "/app")
    public class AppLogin {
    
        @RequestMapping(value = "/login")
        @ResponseBody
        public String login(String loginCode, String password){
            String token = "";
            try {
                token = TokenUtils.creatToken(loginCode);
            } catch (JOSEException e) {
                e.printStackTrace();
            }
            return token;
        }
    }
    @Controller
    @RequestMapping(value = "/app/user")
    public class AppSysUserController {
    
        @RequestMapping(value = "/getLoginName")
        @ResponseBody
        public String getLoginName(){
            return "admin";
        }
    }

        4.调用查看结果

        

        

    
    
  • 相关阅读:
    提高代码质量:如何编写函数
    如何写自我评价
    写简历注意事项
    Android开发注意细节
    Android:onNewIntent()触发机制及注意事项
    Atom与markdown
    Java程序性能优化总结
    Java中的继承与组合
    Fragment生命周期总结
    C# 生成随机姓名
  • 原文地址:https://www.cnblogs.com/chao555/p/9713496.html
Copyright © 2020-2023  润新知