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 」欢迎关注和转载,保留摘要,谢谢! 目录 父子类变量名相同会咋样? 为啥强制子类.父类变量名不同? ...
随机推荐
- luogu3978 [TJOI2015]概率论
题目链接:洛谷 题目大意:求所有$n$个点的有根二叉树的叶子节点数总和/$n$个点的有根二叉树的个数. 数据范围:$n\leq 10^9$ 生成函数神题!!!!(我只是来水博客的) 首先$n$个点的有 ...
- android AsyncTask异步任务(笔记)
AsyncTask是一个专门用来处理后台进程与UI线程的工具.通过AsyncTask,我们可以非常方便的进行后台线程和UI线程之间的交流. 那么AsyncTask是如何工作的哪. AsyncTask拥 ...
- release 步骤
一:在新的 TR 里面创建自己的task 1: /n se01 进入自己的用户名下面 2:display 3:选中自己的名字右键>check object 4:选中自己的名字右键> dir ...
- shmdt() 与 shmctl() 的区别?
操作共享内存,我们用到了下面的函数 ============================================== #include <sys/types.h> #inclu ...
- C#设计模式(9)——装饰者模式(Decorator Pattern)(转)
一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...
- Mybatis(二)总结
1. 输入映射(就是映射文件中可以传入哪些参数类型) 1)基本类型 2)pojo类型 3)Vo类型2. 输出映射(返回的结果集可以有哪些类型) 1)基本类型 2)pojo类型 3)List类型3. 动 ...
- linux之tree命令
linux下tree命令的用法解释 2018年03月22日 ⁄ RakSmart教程 ⁄ 共 583字 ⁄ 字号 小 中 大 ⁄ linux下tree命令的用法解释已关闭评论 tree命令,主要功能是 ...
- linux下视频转gif
title: linux下视频转gif date: 2017-11-23 16:55:26 tags: linux categories: linux 安装ffmpeg ffmpeg是一套非常强大的音 ...
- 2440nandflash启动过程再学习
2011-02-13 12:27:05 2440nandflash启动,先是nandflash的前4K自动复制到CPU的0x0地址开始的4K区域. 然后CPU开始运行这4K(刚才copy过来的代码), ...
- Python数据分析Pandas库方法简介
Pandas 入门 Pandas简介 背景:pandas是一个Python包,提供快速,灵活和富有表现力的数据结构,旨在使“关系”或“标记”数据的使用既简单又直观.它旨在成为在Python中进行实际, ...