JWT ajax java spingmvc 简洁教程
1、添加依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.6.0</version>
</dependency>
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>java-property-utils</artifactId>
<version>1.9.1</version>
</dependency>
2、登录 及登录后获取菜单信息
package com.fescotech.national.common.web.jwt; import io.jsonwebtoken.Claims; import java.io.IOException;
import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import com.fescotech.apps.national.manager.web.api.base.IBaseUserApi;
import com.fescotech.apps.national.manager.web.dto.basic.user.BaseUser;
import com.fescotech.national.common.web.dto.Menu;
import com.fescotech.national.common.web.dto.Res;
import com.fescotech.national.common.web.menu.IMenuProvider; @Controller
public class JWTLoginController {
@Autowired
private IMenuProvider menuProvider;
@Autowired
private IBaseUserApi iBaseUserApi; /**
* 登录
*/
@ResponseBody
@RequestMapping(value = "/jwt/login", method = RequestMethod.POST)
public Res login(String username, String password)throws IOException {
//登录成功后,查询用户信息
BaseUser buS = new BaseUser();
buS.setUserName(username);
BaseUser user = iBaseUserApi.queryUserByLoginName(buS);
//账号不存在或密码错误
if(user == null || !password.equals(user.getUserPwd())) {
return Res.error("0", "账号或密码不正确");
}
//账号不存在或密码错误
if(user.getUserType()!=3) {
return Res.error("0", "非超级管理员不可登录后台");
}
//登录成功返回 客户端 token
String userToken = TokenUtil.getJWTString(user);
LoginOkData ld = new LoginOkData();
ld.setToken(userToken);
return Res.ok("1", "登录成功", ld, 1);
}
/**
* 加载用户权限菜单
*
*/
@ResponseBody
@RequestMapping(value = "/jwt/getMenu", method = RequestMethod.POST)
public Res getMenu(String token){
//接收客户端token 进行验证
Claims claims = TokenUtil.isValid(token, TokenUtil.key);
if(null == claims){
System.out.println("token 验证失败!");
return Res.error("-1", "token失效");
}
//验证通过 获取用户信息
String userId = (String)claims.get("userId");
List<Menu> menuList = menuProvider.getUserMenu(userId, null);
return Res.ok("1", "菜单请求成功", menuList, 1); }
}
3、生成及验证 token
package com.fescotech.national.common.web.jwt; import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map; import com.fescotech.apps.national.manager.web.dto.basic.user.BaseUser; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm; public class TokenUtil {
public static String key = "fescoTecth";
/**
* 生成token 并返回
*
*/
public static String getJWTString(BaseUser user){
Map<String,Object> claims = new HashMap<String,Object>();
claims.put("userName", user.getUserName());
claims.put("userId", user.getUserId());
Date expires = new Date();
Calendar c = Calendar.getInstance();
c.add(Calendar.SECOND, 30);
expires = c.getTime();
SignatureAlgorithm signatureAlgorithm =SignatureAlgorithm.HS256;
String jwtString = Jwts.builder()
.setIssuer("Jersey-Security-Basic")
.setSubject(user.getUserName())
.setAudience("user")
.setExpiration(expires)
.setClaims(claims)
.setIssuedAt(new Date())
.setId(user.getUserId())
.signWith(signatureAlgorithm,key)
.compact();
return jwtString;
} /**
* 验证token 是否有效
*
*/
public static Claims isValid(String token, String key) {
try {
Claims claims = (Claims)Jwts.parser().setSigningKey(key).parseClaimsJws(token.trim()).getBody();
return claims;
} catch (Exception e) {
return null;
}
}
}
4、拦截器 添加允许跨域访问
package com.fescotech.national.common.web.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* 拦截器,允许跨域访问
* @author feiye
*
*/
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*"); //为安全起见,可配置允许访问的请求方地址。这里配置成*号,是允许所有访问。
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); //为安全起见,也可配置成只允许POST请求
response.addHeader("Access-Control-Allow-Headers", "Content-Type,auth_token"); //这里要注意,auth_token是我自定义的请求头当中带的token,在这里必须添加,否则你永远获取不到。
response.addHeader("Access-Control-Max-Age", "60");//30 min
filterChain.doFilter(request, response);
}
}
5、web.xml 添加拦截器配置
<filter>
<filter-name>cros</filter-name>
<filter-class>com.fescotech.national.common.web.filter.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cros</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
6、前端ajax 请求
logins:方法 提交用户名密码 进行登录,登录成功后,获得 token放入全局变量
getMenu:方法,提交 token 服务器进行验证,通过后,获取对应的用户信息,根据用户信息获取对应的权限菜单信息并返回,完成一次数据请求。
登录成功后,每次请求都要带上 token 服务器验证通过后,方可接收请求,否则不处理客户端请求
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="js/jquery.min.js"></script>
<style>
#mains{width:100%}
#imgCode {width: 100px; border:1px solid green;}
</style>
</head>
<body>
<div id="mains">
<input type="input" id="codes" > <br/>
<img id="imgCode" src="http://localhost:61000/nmweb/captcha.jpg"/>
<br/>
<input type="button" onclick="logins()" width="100px" value="登录">
<input type="button" onclick="getMenu()" width="100px" value="菜单">
</div>
<script type="text/javascript">
var token = "";
function logins(){
var code = $("#codes").val();
var preLocalUrl = "http:/localhost:8080/nbmweb";
var url = preLocalUrl+"/jwt/login";
$.ajax({
type: 'POST',
url: url,
data: "username=admin&password=admin&captcha="+code, success:function(msg){
console.log(msg);
var res = jQuery.parseJSON(msg);
var data = res.data;
// var ldData = jQuery.parseJSON(data);
token = data.token;
},
error:function(errors){
console.log(errors);
}
})
}
function getMenu(){
var url = "http://localhost:8080/nbmweb/jwt/getMenu";
console.log("url-->"+url);
console.log("token-->"+token);
$.ajax({
type: 'POST',
url: url,
data:"token="+token,
success:function(msg){
console.log(msg);
},
error:function(errors){
console.log(errors);
}
})
}
</script>
</body>
</html>
7、以上demo 仅做测试,没有理论讲解比较随心,实际使用中,按需优化。
关于,文件上传,获取验证码,token 的刷新和注销,请待下回分解
推荐参考:https://bbs.csdn.net/topics/392006333
JWT ajax java spingmvc 简洁教程的更多相关文章
- 转:精心挑选的12款优秀 jQuery Ajax 分页插件和教程
在这篇文章中,我为大家收集了12个基于 jQuery 框架的 Ajax 分页插件,这些插件都提供了详细的使用教程和演示.Ajax 技术的出现使得 Web 项目的用户体验有了极大的提高,如今借助优秀的 ...
- Shiro+JWT+Spring Boot Restful简易教程
序言 我也是半路出家的人,如果大家有什么好的意见或批评,请务必issue下. 项目地址:https://github.com/Smith-Cruise/Spring-Boot-Shiro . 如果想要 ...
- Java NIO系列教程(三) Channel之Socket通道
目录: <Java NIO系列教程(二) Channel> <Java NIO系列教程(三) Channel之Socket通道> 在<Java NIO系列教程(二) Ch ...
- 12款优秀 jQuery Ajax 分页插件和教程
12款优秀 jQuery Ajax 分页插件和教程 在这篇文章中,我为大家收集了12个基于 jQuery 框架的 Ajax 分页插件,这些插件都提供了详细的使用教程和演示.Ajax 技术的出现使得 W ...
- Java log4j详细教程
Java log4j详细教程 http://www.jb51.net/article/74475.htm
- [转] java书籍(给Java程序猿们推荐一些值得一看的好书 + 7本免费的Java电子书和教程 )
7本免费的Java电子书和教程 1. Thinking in Java (Third Edition) 本书的作者是Bruce Eckel,它一直都是Java最畅销的免费电子书.这本书可以帮助你系统的 ...
- 学习笔记之Java程序设计实用教程
Java程序设计实用教程 by 朱战立 & 沈伟 学习笔记之JAVA多线程(http://www.cnblogs.com/pegasus923/p/3995855.html) 国庆休假前学习了 ...
- End-to-End Tracing of Ajax/Java Applications Using DTrace
End-to-End Tracing of Ajax/Java Applications Using DTrace By Amit Hurvitz, July 2007 Aja ...
- 阿里 Java 手册系列教程:为啥强制子类、父类变量名不同?
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 父子类变量名相同会咋样? 为啥强制子类.父类变量名不同? ...
随机推荐
- [Database.System.Concepts(6th.Edition.2010)].Abraham.Silberschatz. Ch8学习笔记
Database Ch8.relational design 8.1 features of good design 8.1.1 larger alternatives why design is g ...
- day17:递归函数
1,递归函数是一个函数体系,非常的难 2,练习题一 # 3.用map来处理字符串列表,把列表中所有人都变成sb,比方alex_sb name=['alex','wupeiqi','yuanhao',' ...
- 浅谈AC自动机
写在前面:从10月23日开始写这篇博文,离NOIP2018只有十多天了.坚持不停课的倔强蒟蒻(我)尽量每天挤时间多搞一搞信竞(然而还要准备期中考试).NOIP争取考一个好成绩吧. 一.简介 AC自动机 ...
- 17.1-uC/OS-III消息管理(两种消息队列)
1.使用消息队列 消息队列函数: 函数名 功能 OSQCreate() 创建一个消息队列 OSQDel() 删除一个消息队列 OSQFlush() 清空一个消息队列 OSQPend() 任务等待消息 ...
- 15.1-uC/OS-III资源管理(锁调度器)
1.大部分独占资源的方法都是创建临界段:1) 关中断方式2) 锁调度器方式3) 信号量方式4) mutex方式 2.独占共享资源的最快和最简单方法是关中断 然而,关/开中断是和CPU相关的操作,其相关 ...
- java Quartz定时器任务与Spring 的实现
1.xml配置 <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http:/ ...
- TLS握手、中断恢复与证书中心的原因
在双方都拿到随机数A.B.C后,将会使用这三个随机数生成一个对话密钥,然后使用该对话密钥进行对称加密通信,这种方式我们可以看到,安全性取决于随机数C的加密,前面的几个都是明文传的,这里就取决于服务器的 ...
- GO数组
Array(数组) 数组是同一种数据类型元素的集合. 在Go语言中,数组从声明时就确定,使用时可以修改数组成员,但是数组大小不可变化. 数组定义: var 数组变量名 [元素数量]T ]int //定 ...
- html5+PHP,websocket无法连接的问题(Call to undefined function socket_create())
首先是配置文件的问题,打开extension=php_gd2.dll和extension=php_sockets.dll 扩展. 主要注意的是你当前系统使用的php版本和环境变量里面的php版本是否一 ...
- c#高级编程第七版 学习笔记 第三章 对象和类型
第三章 对象和类型 本章的内容: 类和结构的区别 类成员 按值和按引用传送参数 方法重载 构造函数和静态构造函数 只读字段 部分类 静态类 Object类,其他类型都从该类派生而来 3.1 类和结构 ...