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 简洁教程的更多相关文章

  1. 转:精心挑选的12款优秀 jQuery Ajax 分页插件和教程

    在这篇文章中,我为大家收集了12个基于 jQuery 框架的 Ajax 分页插件,这些插件都提供了详细的使用教程和演示.Ajax 技术的出现使得 Web 项目的用户体验有了极大的提高,如今借助优秀的  ...

  2. Shiro+JWT+Spring Boot Restful简易教程

    序言 我也是半路出家的人,如果大家有什么好的意见或批评,请务必issue下. 项目地址:https://github.com/Smith-Cruise/Spring-Boot-Shiro . 如果想要 ...

  3. Java NIO系列教程(三) Channel之Socket通道

    目录: <Java NIO系列教程(二) Channel> <Java NIO系列教程(三) Channel之Socket通道> 在<Java NIO系列教程(二) Ch ...

  4. 12款优秀 jQuery Ajax 分页插件和教程

    12款优秀 jQuery Ajax 分页插件和教程 在这篇文章中,我为大家收集了12个基于 jQuery 框架的 Ajax 分页插件,这些插件都提供了详细的使用教程和演示.Ajax 技术的出现使得 W ...

  5. Java log4j详细教程

    Java log4j详细教程 http://www.jb51.net/article/74475.htm

  6. [转] java书籍(给Java程序猿们推荐一些值得一看的好书 + 7本免费的Java电子书和教程 )

    7本免费的Java电子书和教程 1. Thinking in Java (Third Edition) 本书的作者是Bruce Eckel,它一直都是Java最畅销的免费电子书.这本书可以帮助你系统的 ...

  7. 学习笔记之Java程序设计实用教程

    Java程序设计实用教程 by 朱战立 & 沈伟 学习笔记之JAVA多线程(http://www.cnblogs.com/pegasus923/p/3995855.html) 国庆休假前学习了 ...

  8. 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 ...

  9. 阿里 Java 手册系列教程:为啥强制子类、父类变量名不同?

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 父子类变量名相同会咋样? 为啥强制子类.父类变量名不同? ...

随机推荐

  1. Python脚本之安装linux源码包-Jenkins

    最近开始学Python,按照网上的教程,写了一个Python脚本下载Jenkins并运行的脚本,很简单. 首先使用vi命令编辑一个新文件auto_built_jenkins.py(关于vi的使用可以见 ...

  2. AngularJS实现可伸缩的页面切换

    AngularJS实现可伸缩的页面切换 AngularJS 1.2 通过引入基于纯CSS class的切换和动画,在一个单页面应用创建页面到页面的切换变得更加的容易.只需要使用一个ng-view,让我 ...

  3. Linux 中的 Install命令

    Linux 中的 Install命令 更新时间:2017年09月25日 16:51:45   投稿:mrr   我要评论 install命令的作用是安装或升级软件或备份数据,它的使用权限是所有用户. ...

  4. Cesium 实践

    详细内容请参考教程:https://www.jianshu.com/p/31c3b55a21eb 该教程翻译自官方英文教程,对入门cesium 帮助很大. 2,Cesium项目实例    实践: 问题 ...

  5. MVEAN_day05 Nexus私服对的搭建

    序言:为什么要搭建私服 因为在公司中我们是以团队进行开发的,不在是在自己的本地仓库中进行,我们需要连接公司远程仓库进行jar依赖.在公司的局域网中搭建的私服,然后开发人员连接这台计算机,进行团队开发. ...

  6. python日期加减法操作

    对日期的一些操作: 对日期的一些操作: 1 #日期转化为字符串并得到指定(或系统日期)n天后的日期--@Eillot 2 def dataTimeToString(dsNow=ReservationT ...

  7. Sysinternals Utilities

    https://docs.microsoft.com/zh-cn/sysinternals/ Sysinternals 之前为Winternals公司提供的免费工具,Winternals原本是一间主力 ...

  8. 队列ADT

    队列 队列是FIFO表,使用队列时在队尾(rear)插入元素,称之为入队(enqueue),以及在对头(front)删除并返回元素值,称之为出队(dequeue). 任何表的实现都可以用于实现队列结构 ...

  9. 关于var、let、const的故事

    对于一门编程语言来说,变量与常量是再正常不过的两种,JavaScript是一直解释型的弱类型语言. JavaScript中变量或者常量可以用var.let.const(后两者是ES6的新特性). 1. ...

  10. Android-Gradle(二)

    理解Gradle脚本 当然我们现在讨论的所有内容都是基于Android studio的,所以请先行下载相关工具.当我们创建一个新的工程,Android studio会默认为我们创建三个gradle文件 ...