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. 大数据和Hadoop时代的维度建模和Kimball数据集市

    小结: 1. Hadoop 文件系统中的存储是不可变的,换句话说,只能插入和追加记录,不能修改数据.如果你熟悉的是关系型数据仓库,这看起来可能有点奇怪.但是从内部机制看,数据库是以类似的机制工作,在一 ...

  2. weui开发笔记

    1.标准的weui只是一个css皮肤,当然里面有h5特性所以有一些很好的组件,比如时间选择控件.数字输入框(用于手机号等),在ios——微信中可以做到完美的展示. 2.ui框架以手机移动端为优先显示( ...

  3. js多选下拉框

    1.js原生实现 1.1:引用JS文件 /*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */ !function(a,b ...

  4. 【转】AngularJS动态生成div的ID

    AngularJS动态生成div的ID 原文链接:http://blog.csdn.net/you23hai45/article/details/52348078 1.问题背景 给定一个数组对象,里面 ...

  5. odoo二次开发 tips

    1.model属性 每个对象(即class)一般由字段(变量)和函数组成,每个对象对应着数据库中的一张表,驼峰命名方式 models.Model 基础模块,会根据字段和模型名在后台数据库生成对应得表文 ...

  6. 剑指offer-复杂链表的复制

    题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...

  7. (4.9)mysql备份还原——binlog查看工具之mysqlbinlog的使用

    关键词:mysqlbinlog,mysql binlog查看,二进制文件查看,binlog查看工具,binlog查看方法 常用总结: [1]在test库redo某个binlog中的文件mysqlbin ...

  8. mongodb删除重复数据

    注:mongodb当前版本是3.4.3   插入六条数据:   查询存在重复的数据:   查询并循环删除重复数据:   删除语句解析: db.userInfo.aggregate([     {   ...

  9. 初始化vue项目,报错This is probably not a problem with npm,there is likely additional logging output above

    https://blog.csdn.net/ink_if/article/details/79015811 参考别人的博客 初始化项目,vue init webpack-simple demo 然后n ...

  10. ORACLE中关于使用between在MyBatis中取不同的区间值和取反

    最近在项目中使用between取不同的区间值问题,由于区间跨度大,而且区间多,又是前端传过来的参数,所以使用in和exists比较麻烦.然后就考虑使用between.现将使用方法记录一下. 假如表有个 ...