com.fasterxml.jackson.core
jackson-core
2.9.4
com.fasterxml.jackson.core
jackson-databind
2.9.4
com.fasterxml.jackson.core
jackson-annotations
2.9.4
com.alibaba
fastjson
1.2.41
io.jsonwebtoken
jjwt
0.7.0
com.auth0
java-jwt
3.2.0
org.springframework
spring-context
5.1.3.RELEASE
org.springframework
spring-tx
5.1.3.RELEASE
org.quartz-scheduler
quartz
2.3.0
org.springframework
spring-context-support
5.1.3.RELEASE
org.springframework
spring-test
5.1.3.RELEASE
org.springframework
spring-web
5.1.3.RELEASE
org.springframework
spring-webmvc
5.1.3.RELEASE
org.slf4j
slf4j-log4j12
1.7.16
package com.dqw.util;
import java.security.Key;
import java.util.Date;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/**
* jwt工具类
* @ClassName: JWTUtil
* @Description:TODO
* @author: 丁乾文
* @date: 2019年5月13日 下午7:48:21
*/
public class JWTUtil {
/**
* token加密时使用的密钥
* 一旦得到该密钥也就可以伪造token了
*/
public static String sercetKey = "InMySchoolOnline";
/**
* 代表token的有效时间
*/
public final static long keeptime = 1800000;
/**
* JWT由3个部分组成,分别是 头部Header,载荷Payload一般是用户信息和声明,签证Signature一般是密钥和签名
* 当头部用base64进行编码后一般都会呈现eyJ...形式,而载荷为非强制使用,签证则包含了哈希算法加密后的数据,包括转码后的header,payload和sercetKey
* 而payload又包含几个部分,issuer签发者,subject面向用户,iat签发时间,exp过期时间,aud接收方。
* @Title: generToken
* @Description: TODO
* @param: @param id 用户id
* @param: @param issuer 签发者
* @param: @param subject 一般用户名
* @param: @return
* @return: String
* @throws
*/
public static String generToken(String id, String issuer, String subject) {
long ttlMillis = keeptime;
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
//使用Hash256算法进行加密
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//获取系统时间以便设置token有效时间
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(sercetKey);
//将密钥转码为base64形式,再转为字节码
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
//对其使用Hash256进行加密
JwtBuilder builder = Jwts.builder().setId(id).setIssuedAt(now);
//JWT生成类,此时设置iat,以及根据传入的id设置token
if (subject != null) {
builder.setSubject(subject);
}
if (issuer != null) {
builder.setIssuer(issuer);
}
//由于Payload是非必须加入的,所以这时候要加入检测
builder.signWith(signatureAlgorithm, signingKey);
//进行签名,生成Signature
if (ttlMillis >= 0) {
long expMillis = nowMillis + ttlMillis;
Date exp = new Date(expMillis);
builder.setExpiration(exp);
}
//返回最终的token结果
return builder.compact();
}
/**
* 该函数用于更新token
* @Title: updateToken
* @Description: TODO
* @param: @param token
* @param: @return
* @return: String
* @throws
*/
public static String updateToken(String token) {
//Claims就是包含了我们的Payload信息类
Claims claims = verifyToken(token);
String id = claims.getId();
String subject = claims.getSubject();
String issuer = claims.getIssuer();
//生成新的token,根据现在的时间
return generToken(id, issuer, subject);
}
/**
* 将token解密出来,将payload信息包装成Claims类返回
* @Title: verifyToken
* @Description: TODO
* @param: @param token
* @param: @return
* @return: Claims
* @throws
*/
private static Claims verifyToken(String token) {
Claims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(sercetKey))
.parseClaimsJws(token).getBody();
return claims;
}
}
package com.dqw.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import com.dqw.util.JWTUtil;
import com.dqw.util.ResponseData;
/**
* token鉴定
* @ClassName: HeaderTokenInterceptor
* @Description:TODO
* @author: 丁乾文
* @date: 2019年5月13日 下午8:52:40
*/
public class HeaderTokenInterceptor implements HandlerInterceptor {
private static final Logger LOG = Logger.getLogger(HeaderTokenInterceptor.class);
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object handler) throws Exception {
ResponseData responseData = null;
// 获取我们请求头中的token验证字符
String headerToken = httpServletRequest.getHeader("token");
// 检测当前页面,我们设置当页面不是登录页面时对其进行拦截
// 具体方法就是检测URL中有没有login字符串
if (!httpServletRequest.getRequestURI().contains("login")) {
if (headerToken == null) {
// 如果token不存在的话,返回错误信息。
responseData=ResponseData.customerError();
}
try {
// 对token进行更新与验证
headerToken = JWTUtil.updateToken(headerToken);
LOG.debug("token验证通过,并续期了");
} catch (Exception e) {
LOG.debug("token验证出现异常!");
// 当token验证出现异常返回错误信息,token不匹配
responseData=ResponseData.customerError();
}
}
if(responseData!=null) {//如果有错误信息
httpServletResponse.getWriter().write(JSON.toJSONString(responseData));
return false;
}else {
// 将token加入返回页面的header
httpServletResponse.setHeader("token", headerToken);
return true;
}
}
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o, Exception e) throws Exception {
}
}
package com.dqw.util;
import java.util.HashMap;
import java.util.Map;
/**
* 响应实体
* @ClassName: ResponseData
* @Description:TODO
* @author: 丁乾文
* @date: 2019年5月13日 下午8:53:10
*/
public class ResponseData {
private final String message;
private final int code;
private final Map data = new HashMap();
public String getMessage() {
return message;
}
public int getCode() {
return code;
}
public Map getData() {
return data;
}
public ResponseData putDataValue(String key, Object value) {
data.put(key, value);
return this;
}
private ResponseData(int code, String message) {
this.code = code;
this.message = message;
}
public static ResponseData ok() {
return new ResponseData(200, "Ok");
}
public static ResponseData notFound() {
return new ResponseData(404, "Not Found");
}
public static ResponseData badRequest() {
return new ResponseData(400, "Bad Request");
}
public static ResponseData forbidden() {
return new ResponseData(403, "Forbidden");
}
public static ResponseData unauthorized() {
return new ResponseData(401, "unauthorized");
}
public static ResponseData serverInternalError() {
return new ResponseData(500, "Server Internal Error");
}
public static ResponseData customerError() {
return new ResponseData(1001, "customer Error");
}
}
package com.dqw.po;
/**
* 用户实体类
* @ClassName: User
* @Description:TODO
* @author: 丁乾文
* @date: 2019年5月13日 下午8:43:38
*/
public class User {
private Integer id;
private String email;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
package com.dqw.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
* 主要解决请求跨域问题
* @ClassName: HttpInterceptor
* @Description:TODO
* @author: 丁乾文
* @date: 2019年5月13日 下午8:46:41
*/
public class HttpInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 允许跨域
response.setHeader("Access-Control-Allow-Origin", "*");
// 允许自定义请求头token(允许head跨域)
response.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
package com.dqw.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.dqw.util.ResponseData;
/**
* 首页
* @ClassName: IndexController
* @Description:TODO
* @author: 丁乾文
* @date: 2019年5月13日 下午9:09:35
*/
@RestController
@RequestMapping("index")
public class IndexController {
@GetMapping("index")
public ResponseData toLogin() {
ResponseData responseData = ResponseData.ok();
return responseData;
}
}
package com.dqw.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.dqw.po.User;
import com.dqw.util.JWTUtil;
import com.dqw.util.ResponseData;
/**
* @ClassName: LoginController
* @Description:TODO
* @author: 丁乾文
* @date: 2019年5月13日 下午8:41:47
*/
@RestController
@RequestMapping("login")
public class LoginController {
/**
* 用户登录
* @Title: login
* @Description: TODO
* @param: @param user
* @param: @return
* @return: ResponseData
* @throws
*/
@PostMapping(value="login")
public @ResponseBody ResponseData login(User user) {
//模拟去查询数据库,看是否存在此用户
boolean login = toLogin(user);
ResponseData responseData = ResponseData.ok();
if(login) {
//生成token
String token = JWTUtil.generToken("1", "Jersey-Security-Basic", user.getEmail());
//向浏览器返回token,客户端受到此token后存入cookie中,或者h5的本地存储中
responseData.putDataValue("token", token);
//以及用户
responseData.putDataValue("user", user);
}else {
//用户或者密码错误
responseData=ResponseData.customerError();
}
return responseData;
}
public boolean toLogin(User user) {
if(user.getEmail()!=null&&user.getEmail().trim().length()>0) {
if(user.getEmail().equals("root")) {
if(user.getPassword().equals("123456")) {
return true;
}
}
}
return false;
}
}
}
Insert title here
邮箱:
密码:
欢迎
欢迎你(可以从本地存取获取cookie中获取)