1 /** 2 * 访问后台的对象,为ajax封装 3 * @param url 后台资源路径 4 * @param param Map参数 5 * @param contentType 传输类型 6 * @param success 成功回调函数 7 * @param error 失败回调函数 8 * @param requestType 请求类型(get.post,put,delete) 9 * @constructor 10 */ 11 var Query = function (url,param,contentType,successFunc,errorFunc,requestType) { 12 this.url = url; 13 14 //先确认参数存在 15 if (param) { 16 如果是get请求类型,则将参数拼接到url后面 17 if (requestType == Query.GET_TYPE) { 18 this.param = this._concatParamToURL(param,url); 19 } else { 20 其他请求类型,要根据不同的传输格式来确定传输的值的类型 21 if (contentType == Query.NOMAL_TYPE) { 22 this.param = JSON.parse(._convertParamToJson(param)); 23 } 24 ._convertParamToJson(param); 25 } 26 } 27 } 28 null; 29 } 30 31 32 this.contentType = contentType; 33 this.successFunc = successFunc; 34 this.errorFunc = errorFunc; 35 请求超时,默认10秒 36 this.timeout = 10000 37 是否异步请求,默认异步 38 this.async = true 39 this.requestType = requestType; 40 } 41 42 Query.JSON_TYPE = 'application/json' 43 Query.NOMAL_TYPE = 'application/x-www-form-urlencoded' 44 45 46 * ajax请求的访问 47 * 默认是post 48 * @param url 要访问的地址 49 * @param paramMap 传给后台的Map参数,key为字符串类型 50 * @param callback 回调函数 51 * @param contentType 传输数据的格式 默认传输application/x-www-form-urlencoded格式 52 53 Query.create = 54 return new Query(url,Query.NOMAL_TYPE,Query.GET_TYPE); 55 56 57 -----------------------以下为RESTFul方法--------------------------- 58 ajax请求类型 59 Query.GET_TYPE = "get" 60 Query.POST_TYPE = "post" 61 Query.PUT_TYPE = "put" 62 Query.DELETE_TYPE = "delete" 63 64 get方法默认是Query.NOMAL_TYPE 65 Query.createGetType = 66 67 68 Query.createPostType = 69 70 71 Query.createPutType = 72 73 74 Query.createDeleteType = 75 76 77 78 79 * 将paramMap参数转为json格式 80 * @param paramMap 81 * @private 82 83 Query.prototype._convertParamToJson = (paramMap) { 84 85 return window.tool.strMap2Json(paramMap); 86 87 88 89 90 * 将参数拼接至URL尾部 91 92 * @param url 93 94 95 Query.prototype._concatParamToURL = (paramMap,url) { 96 let size = paramMap.size; 97 98 if (size > 0) { 99 let count = 0100 url = url + "?"101 let urlParam = ""102 103 for (let [k,v] of paramMap) { 104 urlParam = urlParam + encodeURIComponent(k) + "=" + encodeURIComponent(v); 105 if (count < size-1106 urlParam = urlParam + " && "107 count++108 109 110 url = url + urlParam; 111 112 113 114 115 ajax需要跳转的界面 116 Query.REDIRECT_URL = "REDIRECT_URL"117 118 119 * ajax成功返回时调用的方法 120 * 会根据ajax的ContentType类型,转换Response对象的data给回调的成功函数 121 * 如application/json格式类型,data会转成json类型传递 122 * @param queryResult 返回的值,通常为后台的Response对象 123 124 125 Query.prototype._successFunc = (queryResult) { 126 var data = .__afterSuccessComplete(queryResult); 127 if (.successFunc) { 128 .successFunc(data); 129 130 131 如果有需要跳转的页面,则自动跳转 132 if (data && data.REDIRECT_URL != 133 window.location = data.REDIRECT_URL; 134 135 136 137 138 * 会根据ajax的ContentType类型,转换Response对象的data给回调的失败函数 139 140 * 如果对获得的参数不满意,可以用this.getMsg或this.getJsonMsg来进行获取(this指Query对象) 141 * 142 * 这里错误分3种 143 * 1.是Web容器出错 144 * 2.是Filter过滤器主动报错(如一些校验失败后主动抛出,会有错误提示) 145 * 3.是Spring抛出,Spring异常会全局捕捉进行封装 146 147 148 149 Query.prototype._errorFunc = 150 151 返回的信息 152 .__afterErrorComplete(queryResult); 153 如果data里面没东西 154 if (!data) { 155 data = queryResult.statusText; 156 157 158 是否调用者自身已解决了错误 159 var handleError = false160 161 调用回调函数,如果返回结果为true,则不会默认错误处理 162 this.errorFunc instanceof Function) { 163 handleError = .errorFunc(data); 164 165 166 错误编号 167 var code; 168 错误信息 169 msg; 170 171 没有取消对错误的后续处理,那么进行跳转 172 handleError) { 173 174 如果data成功转为Json对象 175 (data) { 176 Filter过滤器主动报错(如一些校验失败后主动抛出,会有错误提示) 177 (data.status) { 178 code = data.status; 179 180 (data.message) { 181 msg = data.message; 182 183 184 185 最终跳转至错误页面 186 var path = "/system/error"187 if (code && msg) { 188 path = path + "/" + error.code + "/" + error.msg; 189 190 window.location.href = path; 191 192 193 194 Query.SUCCESS_TYPE = "SUCCESS_TYPE"195 Query.ERROR_TYPE = "ERROR_TYPE"196 197 * 当一个请求完成时,无论成功或失败,都要调用此函数做一些处理 198 * @param queryResult 服务端返回的数据 199 * @returns {*} 200 201 202 Query.prototype._afterComplete = 203 ._cancleLoadDom(); 204 205 206 207 * 成功的返回处理,会将data部分转为对象 208 * 默认application/json会进行单引号转双引号 209 210 * @param queryResult 211 212 213 214 Query.prototype.__afterSuccessComplete = 215 ._afterComplete(); 216 this.response = queryResult; 217 218 var data = queryResult.data; 219 data必须要有内容,且不是对象才有转换的意义 220 if (data && !(data Object)) { 221 data = .getJsonMsg(); 222 223 data; 224 225 226 227 * 失败的返回处理 228 * 最终会根据ajax的contentType来进行data相应类型转换 229 230 231 232 233 Query.prototype.__afterErrorComplete = 234 235 236 queryResult.responseJSON; 237 238 data = queryResult.responseText; 239 240 241 242 243 244 245 * 取消请求时的等待框 246 247 248 Query.prototype._cancleLoadDom = () { 249 取消加载框 250 .loadDom) { 251 $(this.loadDom).remove("#loadingDiv"); 252 253 254 255 256 * 正式发送ajax 257 258 259 Query.prototype.sendMessage = 260 var self = 261 var xhr = $.ajax( 262 { 263 url: .url,264 type: .requestType,1)">265 contentType: .contentType,1)">266 data: .param,1)">267 ajax发送前调用的方法,初始化等待动画 268 @param XHR XMLHttpRequest对象 269 beforeSend: (XHR) { 270 试图从Cookie中获得token放入http头部 271 var token = window.tool.getCookieMap().get(window.commonStaticValue.TOKEN); 272 (token){ 273 XHR.setRequestHeader(window.commonStaticValue.TOKEN,token); 274 } 275 276 绑定本次请求的queryObj 277 XHR.queryObj = self; 278 if (self.beforeSendFunc 279 self.beforeSendFunc(XHR); 280 281 282 if (self.loadDom HTMLElement) { 283 self.loadDom.innerText = ""284 $(self.loadDom).append("<div id='loadingDiv' class='loading'><img src='/image/loading.gif'/></div>"285 } else jQuery) { 286 self.loadDom.empty(); 287 self.loadDom.append("<div id='loadingDiv' class='loading'><img src='/image/loading.gif'/></div>"288 289 },1)">290 将QueryObj设置为上下文 291 context: self,1)">292 success: ._successFunc,1)">293 error: ._errorFunc,1)">294 complete:(){ 295 console.log("ajax完成"296 297 timeout: .timeout,1)">298 async: .async 299 300 ); 301 302 303 -----------------------------------下面提供了获取后台返回信息方法(帮忙封装了) 304 305 * 获取返回信息Response的Meta头 306 307 Query.prototype.getMeta = 308 .response.meta; 309 310 311 312 * 获得返回值里的data部分 313 314 315 Query.prototype.getMsg = 316 .response.data; 317 318 319 320 * 获得返回值里的data部分,尝试将其转为Json对象 321 322 Query.prototype.getJsonMsg = 323 324 325 先将字符串里的"转为双引号 326 var data = window.tool.replaceAll(data,""","\""327 try{ 328 var jsonData = JSON.parse(data); 329 jsonData; 330 }catch (e) { 331 332 333 334 335 336 ------------------------以下为对Query的参数设置--------------------------- 337 338 * 在ajax发送前设置参数,可以有加载的动画,并且请求完成后会自动取消 339 * @param loadDom 需要显示动画的dom节点 340 * @param beforeSendFunc ajax发送前的自定义函数 341 342 Query.prototype.setBeforeSend = (loadDom,beforeSendFunc) { 343 this.loadDom = loadDom; 344 this.beforeSendFunc = beforeSendFunc; 345 346 347 348 * 设置超时时间 349 * @param timeout 350 351 Query.prototype.setTimeOut = (timeout) { 352 this.timeout = timeout; 353 354 355 Query.prototype.setAsync = (async) { 356 this.async = async; 357 }
<script>alert(123)</>
<!DOCTYPE html> html> head> meta charset="utf-8" /> title></p><body>
1 /** 2 * @auther: NiceBin 3 * @description: 系统的拦截器,注册在FilterConfig类中进行 4 * 不能使用@WebFilter,因为Filter要排序 5 * 1.对ServletRequest进行封装 6 * 2.防止CSRF,检查http头的Referer字段 7 * @date: 2020/12/15 15:32 8 9 @Component 10 public class SystemFilter implements Filter { 11 private final Logger logger = LoggerFactory.getLogger(SystemFilter.class12 @Autowired 13 private Environment environment; 14 15 @Override 16 void init(FilterConfig filterConfig) throws ServletException { 17 logger.info("系统拦截器SystemFilter开始加载"18 19 20 21 void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) IOException,ServletException { 22 SystemHttpServletRequestWrapper requestWrapper = SystemHttpServletRequestWrapper((HttpServletRequest) request); 23 24 检测http的Referer字段,不允许跨域访问 25 String hostPath = environment.getProperty("server.host-path"26 String referer = requestWrapper.getHeader("Referer"27 if(!Tool.isNull(referer)){ 28 if(referer.lastIndexOf(hostPath)!=0){ 29 ((HttpServletResponse)response).setStatus(HttpStatus.FORBIDDEN.value()); //设置错误状态码 30 31 32 33 chain.doFilter(requestWrapper,response); 34 35 36 37 void destroy() { 38 39 40 }
* @description: 包装的httpServlet,进行以下增强 * 1.将流数据取出保存,方便多次读出 * 2.防止XSS攻击,修改读取数据的方法,过滤敏感字符 * @date: 2020/4/23 19:50 7 8 class SystemHttpServletRequestWrapper extends HttpServletRequestWrapper { 9 final byte[] body; 10 HttpServletRequest request; 11 12 public SystemHttpServletRequestWrapper(HttpServletRequest request) IOException { 13 super(request); 14 打印属性 15 printRequestAll(request); 16 body = HttpHelper.getBodyString(request).getBytes(Charset.forName("UTF-8")); //HttpHelper是我自己写的工具类 17 this.request = request; public BufferedReader getReader() 22 new BufferedReader( InputStreamReader(getInputStream())); 23 24 25 26 public ServletInputStream getInputStream() final ByteArrayInputStream bais = ByteArrayInputStream(body); 28 ServletInputStream() { @Override 30 boolean isFinished() { 31 33 35 isReady() { 36 37 40 setReadListener(ReadListener readListener) { 41 42 43 44 45 int read() 46 bais.read(); 47 48 }; 49 50 51 52 * 可以打印出HttpServletRequest里属性的值 53 * @param request 54 55 printRequestAll(HttpServletRequest request){ 56 Enumeration e = request.getHeaderNames(); 57 while (e.hasMoreElements()) { 58 String name = (String) e.nextElement(); 59 String value = request.getHeader(name); 60 System.out.println(name + " = " + value); 61 62 63 64 以下为XSS预防 65 66 public String getParameter(String name) { 67 String value = request.getParameter(name); 68 StringUtils.isEmpty(value)) { 69 value = StringEscapeUtils.escapeHtml4(value); 70 71 value; 72 73 74 75 String[] getParameterValues(String name) { 76 String[] parameterValues = .getParameterValues(name); 77 if (parameterValues == 78 79 80 for (int i = 0; i < parameterValues.length; i++81 String value = parameterValues[i]; 82 parameterValues[i] =83 84 parameterValues; 85 86 }
HttpHelper { 2 * 获取请求中的Body内容 @return 6 7 static String getBodyString(ServletRequest request) { 8 StringBuilder sb = StringBuilder(); 9 InputStream inputStream = 10 BufferedReader reader = 11 12 inputStream = request.getInputStream(); 13 reader = new InputStreamReader(inputStream,Charset.forName("UTF-8"))); 14 String line = ""15 while ((line = reader.readLine()) != 16 sb.append(line); 17 18 } (IOException e) { 19 e.printStackTrace(); 20 } finally21 if (inputStream != 22 inputStream.close(); 24 } e.printStackTrace(); 26 27 if (reader != 29 30 reader.close(); 31 } 35 36 sb.toString(); 38 }
inputStream = request.getInputStream(); reader =String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
* @description: 为了排序Filter,如果Filter有顺序要求 * 那么需要在此注册,设置order(值越低优先级越高) * 其他没顺序需要的,可以@WebFilter注册 * 如@WebFilter(filterName = "SecurityFilter",urlPatterns = "/*",asyncSupported = true) * @date: 2020/12/15 15:48 @Configuration FilterConfig { 13 SystemFilter systemFilter; 14 * 注册SystemFilter,顺序为1,任何其他filter不能比他优先 17 @Bean 19 FilterRegistrationBean filterRegist(){ 20 FilterRegistrationBean filterRegistrationBean = FilterRegistrationBean(); 21 filterRegistrationBean.setFilter(systemFilter); 22 filterRegistrationBean.setName("SystemFilter"23 filterRegistrationBean.addUrlPatterns("/*"24 filterRegistrationBean.setAsyncSupported(25 filterRegistrationBean.setOrder(126 filterRegistrationBean; 28 }
1 SystemHttpServletRequestWrapper requestWrapper = (SystemHttpServletRequestWrapper) request
Father { sayName(){ System.out.println("我是爸爸"); } } class Son Father{ sayName(){ System.out.println("我是儿子" Test { @org.junit.Test void test() Exception { Father father = Son(); otherMethod(father); } otherMethod(Father father){ father.sayName(); } }
{ "alg": "HS256","typ": "JWT" }
{ "sub": "1" }
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload),secret )
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.10.2</version> </dependency> <!--jwt一些工具类--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>
1 ** 2 * @auther: NiceBin 3 * @description: Jwt构造器,创建Token来进行身份记录 4 * jwt由3个部分构成:jwt头,有效载荷(主体,payLoad),签名 5 * @date: 2020/5/7 22:40 6 */ JwtTool { 8 9 以下为JwtTool生成时的主题 10 登录是否还有效 11 static final String SUBJECT_ONLINE_STATE = "online_state" 12 13 以下为载荷固定的Key值 主题 final String SUBJECT = "subject" 16 发布时间 17 final String TIME_ISSUED = "timeIssued" 18 过期时间 19 final String EXPIRATION = "expiration" 20 21 22 * 生成token,参数都是载荷(自定义内容) 23 * 其中Map里为非必要数据,而其他参数为必要参数 24 * subject 主题,token生成干啥用的,用上面的常量作为参数 liveTime 存活时间(秒单位),建议使用TimeUnit方便转换 27 * 如TimeUnit.HOURS.toSeconds(1);将1小时转为秒 = 3600 28 claimMap 自定义荷载,可以为空 30 31 static String createToken(String subject,long liveTime,HashMap<String,String> claimMap) Exception { 32 33 SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; 34 35 毫秒要转为秒 36 long now = System.currentTimeMillis() / 1000 37 38 byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(EncrypRSA.keyString); 39 // Key signingKey = new SecretKeySpec(apiKeySecretBytes,signatureAlgorithm.getJcaName()); 42 JwtBuilder jwtBuilder = Jwts.builder() 43 加密算法 44 .setHeaderParam("alg","HS256") 45 jwt签名 .signWith(signatureAlgorithm,EncrypRSA.convertSecretKey); //这个Key是我自个的密码,你们自己设个字符串也成,这个得保密 47 48 HashMap<String,String> payLoadMap = new HashMap<>(); payLoadMap.put(SUBJECT,subject); payLoadMap.put(TIME_ISSUED,String.valueOf(now)); 51 设置Token的过期时间 52 if (liveTime >= 0 53 long expiration = now + liveTime; 54 payLoadMap.put(EXPIRATION,String.valueOf(expiration)); 55 } 56 throw new SystemException(SystemStaticValue.TOOL_PARAMETER_EXCEPTION_CODE,"liveTime参数异常" 58 59 StringBuilder payLoad = 60 61 62 63 Collections.isEmpty(claimMap)) { payLoadMap.putAll(claimMap); 65 66 67 拼接主题payLoad,采用 key1,value1,key2,value2的格式 68 for (Map.Entry<String,String> entry : payLoadMap.entrySet()) { 69 payLoad.append(entry.getKey()).append(',').append(entry.getValue()).append(',' 71 72 对payLoad进行加密,这样别人Base64URL解密后也不是明文 73 String encrypPayLoad = EncrypRSA.encrypt(payLoad.toString()); 74 75 jwtBuilder.setPayload(encrypPayLoad); 76 77 会自己生成签名,组装 78 jwtBuilder.compact(); 80 81 82 * 私钥解密token信息 83 84 token 85 @return 存有之前定义的Key,value的Map,解析失败则返回null 86 87 HashMap getMap(String token) { 88 Tool.isNull(token)) { 89 90 String encrypPayLoad = Jwts.parser() .setSigningKey(EncrypRSA.convertSecretKey) .parsePlaintextJws(token).getBody(); 93 94 String payLoad = EncrypRSA.decrypt(encrypPayLoad); 95 96 String[] payLoads = payLoad.split("," 97 HashMap<String,String> map = 98 int i = 0; i < payLoads.length - 1; i=i+2 99 map.put(payLoads[i],payLoads[i + 1]); 100 101 map; 102 } (Exception e) { 103 System.out.println("Token解析失败"104 105 106 } 107 110 111 112 * 判断token是否有效 114 map 已经解析过token的map true 为有效 116 117 boolean isAlive(HashMap<String,1)"> map) { 118 119 Collections.isEmpty(map)) { 120 String tokenString = map.get(EXPIRATION); 121 122 Tool.isNull(tokenString)) { 123 long expiration = Long.valueOf(tokenString) / 1000124 long now = System.currentTimeMillis(); 125 if (expiration > now) { 126 127 } 128 130 131 132 133 134 135 136 token 还未被解析的token 139 140 isAlive(String token) { 141 JwtTool.isAlive(JwtTool.getMap(token)); 143 }
本站采用系统自动发货方式,付款后即出现下载入口,如有疑问请咨询在线客服!
售后时间:早10点 - 晚11:30点Copyright © 2024 jiecseo.com All rights reserved. 粤ICP备18085929号
欢迎光临【捷杰建站】,本站所有资源仅供学习与参考,禁止用于商业用途或从事违法行为!
技术营运:深圳市晟艺互动传媒有限公司