简单使用java+token

1 篇文章 0 订阅
1 篇文章 0 订阅

文章简介

  • 最近公司的一款app需要提供token的令牌验证。本人在使用之后总结一些经验让后来之人更快的掌握这一技术。
    什么是token,简单来说token就相当于酒店的门卡。在门卡的有效期内可以打开该酒店的一间房间。转回java,酒店相当于我们的后台方法,token相当于门卡,在token的有效期内可以访问后台中的任意方法。*

话不多说先附代码

 //首先定义一下DES
         DesUtils des = new DesUtils("leemenz"); //自定义密钥

        @RequestMapping(value = "getUserNameBYword", method = RequestMethod.GET)
		@ResponseBody
		public InterfaceUtil<Userinfo> getuserinfo(@RequestParam(value="username")String username,@RequestParam(value="userword")String userword) throws Exception{
			//定义fs为格式化时间
			SimpleDateFormat fs = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
			//定义date为当前系统日期
			Date date = new Date();
			//定义Userinfo的泛型list集合
			List<Userinfo> list = null;
			//定义返回码
			int rcode = 0;
			//定义返回内容
			String rmessage = "";
			//根据用户名密码查询该用户
			Userinfo user=userinfoservice.getUserNameBYword(username, userword);	
			//判断user是否为null
			if(user!=null){
			//判断是否存在token,第一次登陆无token即创建token赋给用户
			if(user.getToken().equals("")){
				//token 由时间戳的形式拼接而成,对生成的token执行des加密
				String token = des.encrypt(fs.format(date));
				user.setToken(token);
				//执行修改用户方法,为首次登陆的用户创建token令牌
				userinfoservice.updateUserinfoBytoken(user);
			}else{
				//如果用户存在token,证明该用户不是首次登陆。
				//通过des的解密方法获得正常的token值
				String jmtoken = des.decrypt(user.getToken());
				//将旧时间转换为date类型
				Date d1 = fs.parse(jmtoken);
				//将新时间转换为date类型
				Date d2 = fs.parse(fs.format(date));
				//新时间减去旧时间获得两个日期之间的时间差,除以1000获得相差的秒数
				long diff = (d2.getTime() - d1.getTime())/1000;
				//对diff进行判断,86400即为一天24小时的秒数
				//如果diff小于86400证明已经过期,为rcode赋值201,为rmessage赋值 “认证权限已过期”,向前台返回
				if(diff>86400){
					rcode = 201;
					rmessage = "认证权限已过期";
					//发送之前将改用户数据库中的token抹除,只需该用户再次重新登录即可拿到新的token令牌
					user.setToken("");
					userinfoservice.updateUserinfoBytoken(user);
					return  new InterfaceUtil<Userinfo>(rcode,rmessage,list);
				}
			}
			list = new ArrayList<Userinfo>();
			//向该泛型list集合中添加user
			list.add(user);
			//判断list的size是否为0,为0表示该list为空
			if(list.size() != 0){
				rcode = 200;
				rmessage = "正常应答";
			}else{
				rcode = 9001;
				rmessage = "系统错误";
			}
			return  new InterfaceUtil<Userinfo>(rcode,rmessage,list);
			}else{
				//如果为null直接返回该状态码
				rcode = 9002;
				rmessage = "用户名或密码错误";
				return  new InterfaceUtil<Userinfo>(rcode,rmessage,list);
			}
		}

其中用到了DES的加密方法

package com.sanfan.utils;
import java.security.Key;

import javax.crypto.Cipher;

/**
 * 使用DES算法对字符串进行加密解密 (加密解密的操作步骤正好相反, 参考 {@link #encrypt(String)}, {@link #decrypt(String)})
 */
public class DesUtils {
    private static String defaultSecretKey = "default_secret_key"; //默认密钥
    private Cipher encryptCipher = null; //加密器
    private Cipher decryptCipher = null; //解密器

    public DesUtils() throws Exception {
        this(defaultSecretKey);
    }

    /**
     * @param secretKey 加密解密使用的密钥
     */
    public DesUtils(String secretKey) {
        Key key;
        try {
            key = getKey(secretKey.getBytes());
            encryptCipher = Cipher.getInstance("DES");
            encryptCipher.init(Cipher.ENCRYPT_MODE, key);
            decryptCipher = Cipher.getInstance("DES");
            decryptCipher.init(Cipher.DECRYPT_MODE, key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 加密 (逻辑: 1. 将要加密的字符串转换为字节数组(byte array)<br/>
     *            2. 将第一步的字节数组作为输入使用加密器(Cipher)的doFinal方法进行加密, 返回字节数组<br/>
     *            3. 把加密后的字节数组转换成十六进制的字符串)<br/>
     * @param strIn 要加密的字符串
     * @return 返回加密后的十六进制字符串
     * @throws Exception
     */
    public String encrypt(String strIn) throws Exception {
        return byteArr2HexStr(encrypt(strIn.getBytes()));
    }

    public byte[] encrypt(byte[] arrB) throws Exception {
        return encryptCipher.doFinal(arrB);
    }

    /**
     * 解密 (逻辑: 1. 把加密后的十六进制字符串转换成字节数组(byte array)<br/>
     *            2. 将第一步的字节数组作为输入使用加密器(Cipher)的doFinal方法进行解密, 返回字节数组(byte array)<br/>
     *            3. 把解密后的字节数组转换成字符串)<br/>
     * @param strIn
     * @return
     * @throws Exception
     */
    public String decrypt(String strIn) throws Exception {
        return new String(decrypt(hexStr2ByteArr(strIn)));
    }

    public byte[] decrypt(byte[] arrB) throws Exception {
        return decryptCipher.doFinal(arrB);
    }

    public static String byteArr2HexStr(byte[] arrB) throws Exception {
        int iLen = arrB.length;
        // 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍
        StringBuffer sb = new StringBuffer(iLen * 2);
        for (int i = 0; i < iLen; i++) {
            int intTmp = arrB[i];
            // 把负数转换为正数
            while (intTmp < 0) {
                intTmp = intTmp + 256;
            }
            // 小于0F的数需要在前面补0
            if (intTmp < 16) {
                sb.append("0");
            }
            sb.append(Integer.toString(intTmp, 16));
        }
        return sb.toString();
    }

    public static byte[] hexStr2ByteArr(String strIn) throws Exception {
        byte[] arrB = strIn.getBytes();
        int iLen = arrB.length;
        // 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
        byte[] arrOut = new byte[iLen / 2];
        for (int i = 0; i < iLen; i = i + 2) {
            String strTmp = new String(arrB, i, 2);
            arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
        }
        return arrOut;
    }

    private Key getKey(byte[] arrBTmp) throws Exception {
        // 创建一个空的8位字节数组(默认值为0)
        byte[] arrB = new byte[8];
        // 将原始字节数组转换为8位
        for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
            arrB[i] = arrBTmp[i];
        }
        // 生成密钥
        Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES");
        return key;
    }


    /**
     * 用法实例
     */
    public static void main(String[] args) {
        try {
            String test = "liwc";
            //注意这里,自定义的加密的KEY要和解密的KEY一致,这就是钥匙,如果你上锁了,却忘了钥匙,那么是解密不了的
            DesUtils des = new DesUtils("leemenz"); //自定义密钥
            System.out.println("加密前的字符:" + test);
            System.out.println("加密后的字符:" + des.encrypt(test));
            System.out.println("解密后的字符:" + des.decrypt(des.encrypt(test)));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

最后我们在拦截器里写拦截一下就可以了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 2实用教程(第三版)实验指导与习题解答 清华大学出版社 (编著 耿祥义 张跃平) 实验模版代码 建议使用文档结构图 (选择Word菜单→视图→文档结构图) 上机实践1 初识Java 4 实验1 一个简单的应用程序 4 实验2 一个简单Java Applet程序 4 实验3 联合编译 5 上机实践2 基本数据类型与控制语句 6 实验1 输出希腊字母表 6 实验2 回文数 6 实验3 猜数字游戏 8 上机实践3 类与对象 9 实验1 三角形、梯形和圆形的类封装 9 实验2 实例成员与类成员 12 实验3 使用package语句与import语句 13 上机实践4 继承与接口 15 实验1 继承 15 实验2 上转型对象 17 实验3 接口回调 18 上机实践5 字符串、时间与数字 19 实验1 String类的常用方法 19 实验2 比较日期的大小 21 实验3 处理大整数 22 上机实践6 组件及事件处理 23 实验1 算术测试 23 实验2 信号灯 25 实验3 布局与日历 28 上机实践7 组件及事件处理2 31 实验1 方程求根 31 实验2 字体对话框 34 实验3 英语单词拼写训练 37 上机实践8 多线程 41 实验1 汉字打字练习 41 实验2 旋转的行星 43 实验3 双线程接力 47 上机实践9 输入输出流 50 实验1 学读汉字 50 实验2 统计英文单词字 53 实验2 读取Zip文件 56 上机实践10 Java 中的网络编程 57 实验1 读取服务器端文件 57 实验2 使用套接字读取服务器端对象 59 实验3 基于UDP的图像传输 62 上机实践11 数据结构 66 实验1 扫雷小游戏 66 实验2 排序与查找 70 实验3 使用TreeSet排序 72 上机实践12 java Swing 74 实验1 JLayeredPane分层窗格 74 实验2 使用表格显示日历 75 实验3 多文档界面(MDI) 78 上机实践1 初识Java 实验1 一个简单的应用程序 2.模板代码 Hello.java package 实验一; public class Hello { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("你好,很高兴学习Java"); //命令行窗口输出"你好,很高兴学习Java" A a=new A(); a.fA(); } } class A { void fA() {System.out.println("we are student"); } } 实验2 一个简单Java Applet程序 2.模板代码 FirstApplet.java import java.applet.*; import java.awt.*; public class FirstApplet extends Applet { public void paint(Graphics g) { g.setColor(Color.blue); g.drawString("这是一个Java Applet 程序",10,30);//在Java Applet中绘制一行文字:“这是一个Java Applet 程序” g.setColor(Color.red); g.setFont(new Font("宋体",Font.BOLD,36)); g.drawString("我改变了字体",20,50);//在Java Applet中绘制一行文字:“我改变了字体” } }实验3 联合编译 2.模板代码 public class MainClass { public static void main (String args[ ]) { System.out.println("你好,只需编译我") ; //命令行窗口输出"你好,只需编译我" A a=new A(); a.fA(); B b=new B(); b.fB(); } } public class A { void fA() {
MLDN 李兴华 Java Web 开发实战经典.pdf (高清版) 带有书签,清华大学出版社 第1章 JAVA WEB开发简介 1.1、WEB发展历程 1.2、企业开发架构 1.3、JAVA EE架构 1.4、JAVA EE核心设计模式 1.5、Struts开发框架 1.6、本章摘要 1.7、开发实战讲解 第2章 HTML、JavaScript简介 2.1、服务器与浏览器 2.2、HTML简介 2.2.1、HTML元素概览 2.2.2、创建显示WEB页 2.2.3、创建表单WEB页 2.3、JavaScript简介 2.3.1、JavaScript的基本语法 2.3.2、事件处理 2.3.3、window对象 2.4、本章摘要 2.5、开发实战讲解 第3章 XML简介 3.1、认识XML 3.2、XML解析 3.2.1、DOM解析操作 3.2.2、SAX解析操作 3.2.3、XML解析的好帮手:JDOM 3.2.4、最出色的解析工具:DOM4J 3.3、使用JavaScript操作DOM 3.4、开发实战讲解(基于Oracle数据库) 第4章 Tomcat服务器的安装及配置 4.1、Web容器简介 4.2、Tomcat简介 4.3、Tomcat服务器的下载及配置 4.3.1、Tomcat下载 4.3.2、Tomcat安装 4.3.3、服务器配置 4.4、编写第一个jsp文件 4.5、交互性 4.6、本章摘要 4.7、开发实战讲解 第5章 JSP基础语法 5.1、JSP注释 5.2、Scriptlet 5.2.1、第一种Scriptlet:<%%> 5.2.2、第二种Scriptlet:<%!%> 5.2.3、第三种Scriptlet:<%=%> 5.3、Scriptlet标签 5.4、page指令 5.4.1、设置页面的MIME 5.4.2、设置文件编码 5.4.3、错误页的设置 5.4.4、数据库连接操作 5.5、包含指令 5.5.1、静态包含 5.5.2、动态包含 5.6、跳转指令 5.7、实例操作:用户登陆程序实现(JSP + JDBC实现) 5.7.1、创建数据库表 5.7.2、程序实现思路 5.7.3、程序实现 5.8、本章摘要 5.9、开发实战讲解(基于Oracle数据库) 第6章 JSP内置对象 6.1、JSP内置对象概览 6.2、四种属性范围 6.2.1、page属性范围(pageContext范围) 6.2.2、request属性范围 6.2.3、session属性范围 6.2.4、application属性范围 6.2.5、深入研究page属性范围 6.3、request对象 6.3.1、乱码解决 6.3.2、接收请求参数 6.3.3、显示全部的头信息 6.3.4、角色验证 6.3.5、其他操作 6.4、response对象 6.4.1、设置头信息 6.4.2、页面跳转 6.4.3、操作Cookie 6.5、session对象 6.5.1、取得Session Id 6.5.2、登陆及注销 6.5.3、判断新用户 6.5.4、取得用户的操作时间 6.6、application对象 6.6.1、取得虚拟目录对应的绝对路径 6.6.2、范例讲解:网站计数器 6.6.3、查看application范围的属性 6.7、WEB安全性及config对象 6.7.1、WEB安全性 6.7.2、config对象 6.8、out对象 6.9、pageContext对象 6.10、本章摘要 6.11、开发实战讲解(基于Oracle数据库) 第7章 JavaBean 7.1、JavaBean简介 7.2、在JSP中使用JavaBean 7.2.1、WEB开发的标准目录结构 7.2.2、使用JSP的page指令导入所需要的JavaBean 7.2.3、使用<jsp:useBean>指令 7.3、JavaBean与表单 7.4、设置属性:<jsp:setProperty> 7.4.1、设置指定的属性 7.4.2、指定设置属性的参数 7.4.3、为属性设置具体内容 7.5、取得属性:<jsp:getProperty> 7.6、JavaBean的保存范围 7.6.1、page范围的JavaBean 7.6.2、request范围的JavaBean 7.6.3、session范围的JavaBean 7.6.4、application范围的JavaBean 7.7、JavaBean的删除 7.8、实例操作:注册验证 7.9、DAO设计模式 7.9.1、DAO设计模式简介 7.9.2、DAO开发 7.9.3、JSP调用DAO 7.10、本章摘要 7.11、开发实战讲解(基于Oracle数据库) 第8章 文件上传 8.1、smartupload上传组件 8.1.1、上传单个文件 8.1.2、混合表单 8.1.3、为上传文件自动命名 8.1.4、批量上传 8.2、FileUpload 8.2.1、使用FileUpload接收上传内容 8.2.2、保存上传内容 8.2.3、开发FileUpload组件的专属操作类 8.3、本章摘要 8.4、开发实战讲解(基于Oracle数据库) 第9章 Servlet程序开发 9.1、Servlet简介 9.2、永远的“HelloWorld”:第一个Servlet程序 9.3、Servlet与表单 9.4、Servlet生命周期 9.5、取得初始化配置信息 9.6、取得其他内置对象 9.6.1、取得HttpSession实例 9.6.2、取得ServletContext实例 9.7、Servlet跳转 9.7.1、客户端跳转 9.7.2、服务器端跳转 9.8、WEB开发模式:Mode I与Mode II 9.8.1、Mode I 9.8.2、Mode II:Model-View-Controller 9.9、实例操作:MVC设计模式应用 9.10、过滤器 9.10.1、过滤器的基本概念 9.10.2、实现过滤器 9.10.3、过滤器的应用 9.11、监听器 9.11.1、对application监听 9.11.2、对session监听 9.11.3、对request监听 9.11.4、监听器实例 —— 在线人员统计 9.12、本章摘要 9.13、开发实战讲解(基于Oracle数据库) 第10章 表达式语言 10.1、表达式语言简介 10.2、表达式语言的内置对象 10.2.1、访问四种属性范围的内容 10.2.2、调用内置对象操作 10.2.3、接收请求参数 10.3、集合操作 10.4、在MVC中应用表达式语言 10.5、运算符 10.6、本章摘要 10.7、开发实战讲解(基于Oracle数据库) 第11章 Tomcat数据源 11.1、数据源操作原理 11.2、在Tomcat中使用数据库连接池 11.3、查找数据源 11.4、本章摘要 第12章 JSP标签编程 12.1、标签编程简介 12.2、定义一个简单的标签 —— 空标签 12.3、定义有属性的标签 12.4、TagSupport类 12.5、定义有标签体的标签库 12.6、开发迭代标签 12.7、BodyTagSupport类 12.8、TagExtraInfo类和VariableInfo类 12.9、使用BodyTagSupport开发迭代输出 12.10、简单标签 12.11、DynamicAttributes接口 12.12、本章摘要 第13章 标准标签库(JSTL) 13.1、JSTL简介 13.2、安装JSTL 1.2 13.3、核心标签库 13.3.1、<c:out>标签 13.3.2、<c:set>标签 13.3.3、<c:remove>标签 13.3.4、<c:catch>标签 13.3.5、<c:if>标签 13.3.6、<c:choose>、<c:when>、<c:otherwise>标签 13.3.7、<c:forEach>标签 13.3.8、<c:forTokens>标签 13.3.9、<c:import>标签 13.3.10、<c:url>标签 13.3.11、<c:redirect>标签 13.4、国际化标签库 13.4.1、<fmt:setLocale>标签 13.4.2、<fmt:requestEncoding>标签 13.4.3、读取资源文件 13.4.4、数字格式化标签 13.4.5、日期时间格式化标签 13.4.6、设置时区 13.5、SQL标签库 13.5.1、<sql:setDataSource> 13.5.2、数据库操作标签 13.5.3、事务处理 13.6、XML标签库 13.6.1、XPath简介 13.6.2、<x:parse>标签 13.6.3、<x:out>标签 13.6.4、<x:set>标签 13.6.5、<x:if>标签 13.6.6、<x:choose>、<x:when>、<x:otherwise>标签 13.6.7、<x:forEach>标签 13.7、函数标签库 13.8、本章摘要 13.9、开发实战讲解(基于Oracle数据库) 第14章 AJAX开发技术 14.1、AJAX技术简介 14.2、XMLHttpRequest对象 14.3、第一个AJAX程序 14.4、异步验证 14.5、返回XML数据 14.6、本章摘要 14.7、开发实战讲解(基于Oracle数据库) 第15章 Struts基础开发 15.1、Struts简介 15.2、配置Struts开发环境 15.3、开发第一个Struts程序 15.4、Struts工作原理 15.5、深入Struts应用 15.6、本章摘要 15.7、开发实战讲解(基于Oracle数据库) 第16章 Struts常用标签库 16.1、Struts标签库简介 16.2、Bean标签 16.2.1、<bean:define>标签 16.2.2、<bean:size>标签 16.2.3、资源访问标签 16.2.4、<bean:write>标签 16.2.5、<bean:include>标签 16.2.6、<bean:resource>标签 16.2.7、国际化与<bean:message>标签 16.3、Logic标签 16.3.1、<logic:present>标签和<logic:notPresent>标签 16.3.2、<logic:empty>标签和<logic:notEmpty>标签 16.3.3、关系运算标签 16.3.4、<logic:iterate>标签 16.3.5、重定向标签:<logic:redirect> 16.4、Html标签 16.4.1、<html:form>标签 16.4.2、<html:text>与<html:password>标签 16.4.3、<html:radio>标签 16.4.5、<html:textarea>标签 16.4.6、<html:hidden>标签 16.4.7、按钮标签 16.4.8、实例:编写基本表单 16.4.9、复选框标签 16.4.10、下拉列表框 16.5、本章摘要 16.6、开发实战讲解(JSP + Oracle) 第17章 Struts高级开发 17.1、Struts多人开发 17.2、Token 17.3、文件上传 17.4、动态ActionForm 17.5、Action深入 17.5.1、ForwardAction 17.5.2、IncludeAction 17.5.3、DispatchAction 17.6、验证框架 附录A:实用工具 18.1、JavaMail 18.1.1、James邮件服务器的下载及配置 18.1.2、JavaMail简介及配置 18.1.3、发送普通邮件 18.1.4、发送带附件的HTML风格邮件 18.2、操作Excel文件 18.2.1、JExcelAPI简介 18.2.2、创建一个Excel文件 18.2.3、读取Excel文件 18.2.4、格式化文本 18.3、本章摘要 附录B:MyEclipse开发工具 19.1、MyEclipse简介 19.2、MyEclipse的安装 19.3、MyEclipse的使用 19.4、配置Tomcat服务器 19.5、MyEclipse卸载 19.6、本章摘要 附录C:HTTP状态码及头信息 20.1、HTTP状态码 20.2、HTTP头信息

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值