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-tokenTimeentry: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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。