java token生成和校验的实例代码
现在越来越多的登录方式都用到了token作为用户登录令牌,所以实现了一个token生成和校验案例。
缺点:该实现方式token是存储在内存中,不适合分布式项目,如需改为分布式项目部署,可把token存储在redis中,其中的实现原理还是保持不变。
一)token编码工具类
packagecom.oysept.token.utils; /** *token编码工具类 *@authorouyangjun */ publicclassTokenEncryptUtils{ //编码密码,可自定义 privatestaticfinalStringENCODED_PASSWORD="ouyangjun"; /** *编码 *@paramstr *@return */ publicstaticStringencoded(Stringstr){ returnstrToHex(encodedString(str,ENCODED_PASSWORD)); } /** *转换 *@paramstr *@parampassword *@return */ privatestaticStringencodedString(Stringstr,Stringpassword){ char[]pwd=password.toCharArray(); intpwdLen=pwd.length; char[]strArray=str.toCharArray(); for(inti=0;i二)token生成和校验工具类(包含main方法测试)
packagecom.oysept.token.utils; importjava.util.HashMap; importjava.util.Map; importjava.util.Map.Entry; /** *token生成和校验 *@authorouyangjun */ publicclassTokenUtils{ privatestaticMapMAP_TOKENS=newHashMap (); privatestaticfinalintVALID_TIME=60*60*2;//token有效期(秒) publicstaticfinalStringTOKEN_ERROR="F";//非法 publicstaticfinalStringTOKEN_OVERDUE="G";//过期 publicstaticfinalStringTOKEN_FAILURE="S";//失效 /** *生成token,该token长度不一致,如需一致,可自行MD5或者其它方式加密一下 *该方式的token只存在磁盘上,如果项目是分布式,最好用redis存储 *@paramstr:该字符串可自定义,在校验token时要保持一致 *@return */ publicstaticStringgetToken(Stringstr){ Stringtoken=TokenEncryptUtils.encoded(getCurrentTime()+","+str); MAP_TOKENS.put(str,token); returntoken; } /** *校验token的有效性 *@paramtoken *@return */ publicstaticStringcheckToken(Stringtoken){ if(token==null){ returnTOKEN_ERROR; } try{ String[]tArr=TokenEncryptUtils.decoded(token).split(","); if(tArr.length!=2){ returnTOKEN_ERROR; } //token生成时间戳 inttokenTime=Integer.parseInt(tArr[0]); //当前时间戳 intcurrentTime=getCurrentTime(); if(currentTime-tokenTime entry:MAP_TOKENS.entrySet()){ String[]tArr=TokenEncryptUtils.decoded(entry.getValue()).split(","); inttokenTime=Integer.parseInt(tArr[0]); if(currentTime-tokenTime>VALID_TIME){ MAP_TOKENS.remove(entry.getKey()); } } } /** *测试 *@paramargs */ publicstaticvoidmain(String[]args){ Stringstr="username_and_password"; //获取token Stringtoken=TokenUtils.getToken(str); System.out.println("tokenResult:"+token); //校验token StringcheckToken=TokenUtils.checkToken(token); System.out.println("checkTokenResult:"+checkToken); if(str.equals(checkToken)){ System.out.println("==>tokenverificationsucceeded!"); } } } 补充知识:JAVA后端生成Token(令牌),用于校验客户端,防止重复提交
1.概述:在web项目中,服务端和前端经常需要交互数据,有的时候由于网络相应慢,客户端在提交某些敏感数据(比如按照正常的业务逻辑,此份数据只能保存一份)时,如果前端多次点击提交按钮会导致提交多份数据,这种情况我们是要防止发生的。
2.解决方法:
①前端处理:在提交之后通过js立即将按钮隐藏或者置为不可用。
②后端处理:对于每次提交到后台的数据必须校验,也就是通过前端携带的令牌(一串唯一字符串)与后端校验来判断当前数据是否有效。
3.总结:第一种方法相对来说比较简单,但是安全系数不高,第二种方法从根本上解决了问题,所以我推荐第二种方法。
4.核心代码:
生成Token的工具类:
/** *生成Token的工具类: */ packagered.hearing.eval.modules.token; importjava.security.MessageDigest; importjava.security.NoSuchAlgorithmException; importjava.util.Random; importsun.misc.BASE64Encoder; /** *生成Token的工具类 *@authorzhous *@since2018-2-2313:59:27 * */ publicclassTokenProccessor{ privateTokenProccessor(){}; privatestaticfinalTokenProccessorinstance=newTokenProccessor(); publicstaticTokenProccessorgetInstance(){ returninstance; } /** *生成Token *@return */ publicStringmakeToken(){ Stringtoken=(System.currentTimeMillis()+newRandom().nextInt(999999999))+""; try{ MessageDigestmd=MessageDigest.getInstance("md5"); bytemd5[]=md.digest(token.getBytes()); BASE64Encoderencoder=newBASE64Encoder(); returnencoder.encode(md5); }catch(NoSuchAlgorithmExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } returnnull; } }Token通用工具类:
/** * */ packagered.hearing.eval.modules.token; importjavax.servlet.http.HttpServletRequest; importorg.apache.commons.lang3.StringUtils; /** *Token的工具类 *@authorzhous *@since2018-2-2314:01:41 * */ publicclassTokenTools{ /** *生成token放入session *@paramrequest *@paramtokenServerkey */ publicstaticvoidcreateToken(HttpServletRequestrequest,StringtokenServerkey){ Stringtoken=TokenProccessor.getInstance().makeToken(); request.getSession().setAttribute(tokenServerkey,token); } /** *移除token *@paramrequest *@paramtokenServerkey */ publicstaticvoidremoveToken(HttpServletRequestrequest,StringtokenServerkey){ request.getSession().removeAttribute(tokenServerkey); } /** *判断请求参数中的token是否和session中一致 *@paramrequest *@paramtokenClientkey *@paramtokenServerkey *@return */ publicstaticbooleanjudgeTokenIsEqual(HttpServletRequestrequest,StringtokenClientkey,StringtokenServerkey){ Stringtoken_client=request.getParameter(tokenClientkey); if(StringUtils.isEmpty(token_client)){ returnfalse; } Stringtoken_server=(String)request.getSession().getAttribute(tokenServerkey); if(StringUtils.isEmpty(token_server)){ returnfalse; } if(!token_server.equals(token_client)){ returnfalse; } returntrue; } }使用方法:
①在输出前端页面的时候调用TokenTools.createToken方法,会把本次生成的token放入session中。
②然后在前端页面提交数据时从session中获取token,然后添加到要提交的数据中。
③服务端接受数据后调用judgeTokenIsEqual方法判断两个token是否一致,如果不一致则返回,不进行处理。
备注:tokenClientkey和tokenServerkey自定义,调用judgeTokenIsEqual方法时的tokenClientkey一定要与前端页面的key一致。
以上这篇javatoken生成和校验的实例代码就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。