赞
踩
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- <version>2.9.4</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.9.4</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>2.9.4</version>
- </dependency>
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.41</version>
- </dependency>
- <dependency>
- <groupId>io.jsonwebtoken</groupId>
- <artifactId>jjwt</artifactId>
- <version>0.7.0</version>
- </dependency>
- <dependency>
- <groupId>com.auth0</groupId>
- <artifactId>java-jwt</artifactId>
- <version>3.2.0</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>5.1.3.RELEASE</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>5.1.3.RELEASE</version>
- </dependency>
-
- <dependency>
- <groupId>org.quartz-scheduler</groupId>
- <artifactId>quartz</artifactId>
- <version>2.3.0</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <version>5.1.3.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
- <version>5.1.3.RELEASE</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>5.1.3.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>5.1.3.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>1.7.16</version>
- </dependency>
- 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<String, Object> data = new HashMap<String, Object>();
-
- public String getMessage() {
- return message;
- }
-
- public int getCode() {
- return code;
- }
-
- public Map<String, Object> 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;
- }
- }
-
- }
-
-
- <context:component-scan base-package="com"></context:component-scan>
- <!-- 启动注解驱动 -->
- <mvc:annotation-driven/>
- <context:annotation-config></context:annotation-config>
- <mvc:interceptors>
- <!-- 允许跨域 -->
- <mvc:interceptor>
- <mvc:mapping path="/**"/>
- <bean class="com.dqw.interceptor.HttpInterceptor"></bean>
- </mvc:interceptor>
- <!-- 检验Token -->
- <mvc:interceptor>
- <mvc:mapping path="/**"/>
- <bean class="com.dqw.interceptor.HeaderTokenInterceptor"></bean>
- </mvc:interceptor>
- </mvc:interceptors>
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Insert title here</title>
- <script type="text/javascript" src="jquery.min.js"></script>
- <script type="text/javascript" src="jquery.cookie.js"></script>
- </head>
- <body>
- 邮箱:<input type="text" name="email"><br>
- 密码:<input type="text" name="password"><br>
- <input type="submit" onclick="signIn()" value="登录">
- <script type="text/javascript">
- /**
- * 登录ajax,登录成功后获取后台返回的token,并把token保存到cookie中
- * 以后用户每次请求后台数据需要携带此token
- */
- function signIn() {
- let email = $("input[name='email']").val();
- let password = $("input[name='password']").val();
- $.ajax({
- url: "http://localhost:8080/jwt/login/login.action",
- type: "POST",
- dataType: "json",
- data: {email: email, password: password},
- success: function (result) {
- if(result.code==200){
- //保存token用来判断用户是否登录,和身份是否属实
- $.cookie('token', result.data.token);
- //$.cookie('user', result.data.user);
- //转向主页面
- location="index.html";
- }else{
- alert("用户名或者密码错误!");
- }
- }
- })
- }
- </script>
- </body>
- </html>
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>欢迎</title>
- <script type="text/javascript" src="jquery.min.js"></script>
- <script type="text/javascript" src="jquery.cookie.js"></script>
- </head>
- <body>
- 欢迎你(可以从本地存取获取cookie中获取)
- <br>
- <button onclick="logout()">注销</button>
- <script type="text/javascript">
- /**
- * 请求数据的ajax,需要从cookie读取token放入head传给后台。
- */
- loadDeptTree();
- function loadDeptTree() {
- $.ajax({
- // 自定义的headers字段,会出现option请求,在GET请求之前,后台要记得做检验。
- headers: {
- token: $.cookie('token')
- },
- url: "http://localhost:8080/jwt/index/index.action",
- type: 'GET',
- dataType: 'json',
- success : function (result) {
- if(result.code==200){
- alert("加载到的数据:"+result+",并进行渲染页面.....");
- }else{
- alert("异常,非法token,这里不直接判断是否token不对,实际开发需要各种判断返回码。");
- }
- }
- })
- }
- /**
- * 注销,清空所有cookie(或者只清空保存着token的Cookie就行)
- */
- function logout() {
- var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
- if(keys) {
- for(var i = keys.length; i--;)
- document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
- }
- //返回登录页面或者主页
- window.location.href = "login.html";
- }
- </script>
- </body>
- </html>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。