From 36413ab9b833df623fb38d67361994d72d5db4d6 Mon Sep 17 00:00:00 2001
From: cicadasmile <1327880701@qq.com>
Date: Wed, 10 Jul 2019 22:16:12 +0800
Subject: [PATCH] =?UTF-8?q?SpringBoot2.0=20=E6=95=B4=E5=90=88=20JWT=20?=
=?UTF-8?q?=E6=A1=86=E6=9E=B6,=E8=A7=A3=E5=86=B3Token=E8=B7=A8=E5=9F=9F?=
=?UTF-8?q?=E9=AA=8C=E8=AF=81=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 5 +-
pom.xml | 2 +
ware-jwt-token/pom.xml | 48 ++++++++++++++
.../java/com/jwt/token/JwtApplication.java | 11 ++++
.../java/com/jwt/token/config/JwtConfig.java | 66 +++++++++++++++++++
.../java/com/jwt/token/config/WebConfig.java | 20 ++++++
.../jwt/token/controller/TokenController.java | 44 +++++++++++++
.../token/interceptor/TokenInterceptor.java | 44 +++++++++++++
.../src/main/resources/application.yml | 13 ++++
9 files changed, 252 insertions(+), 1 deletion(-)
create mode 100644 ware-jwt-token/pom.xml
create mode 100644 ware-jwt-token/src/main/java/com/jwt/token/JwtApplication.java
create mode 100644 ware-jwt-token/src/main/java/com/jwt/token/config/JwtConfig.java
create mode 100644 ware-jwt-token/src/main/java/com/jwt/token/config/WebConfig.java
create mode 100644 ware-jwt-token/src/main/java/com/jwt/token/controller/TokenController.java
create mode 100644 ware-jwt-token/src/main/java/com/jwt/token/interceptor/TokenInterceptor.java
create mode 100644 ware-jwt-token/src/main/resources/application.yml
diff --git a/README.md b/README.md
index 3f08ac8..b552f5c 100644
--- a/README.md
+++ b/README.md
@@ -21,9 +21,12 @@
7、SpringBoot2.0 整合 Dubbo框架 ,实现RPC服务远程调用
-
+
8、SpringBoot2.0 整合 ElasticSearch框架,实现高性能搜索引擎
+
+9、SpringBoot2.0 整合 JWT 框架,解决Token跨域验证问题
+
持续更新中...
## 项目简介
diff --git a/pom.xml b/pom.xml
index 5e5cb14..0d28f13 100644
--- a/pom.xml
+++ b/pom.xml
@@ -33,6 +33,8 @@
ware-dubbo-parent
ware-elastic-search
+
+ ware-jwt-token
diff --git a/ware-jwt-token/pom.xml b/ware-jwt-token/pom.xml
new file mode 100644
index 0000000..80e2bb7
--- /dev/null
+++ b/ware-jwt-token/pom.xml
@@ -0,0 +1,48 @@
+
+
+
+ org.springframework.boot
+ spring-boot-starters
+ 2.1.3.RELEASE
+
+ 4.0.0
+ com.jwt.token
+ ware-jwt-token
+ jar
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ io.jsonwebtoken
+ jjwt
+ 0.7.0
+
+
+
+
+
+ ${project.artifactId}
+
+
+ src/main/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.3.2
+
+
+ 1.8
+
+
+
+
+
\ No newline at end of file
diff --git a/ware-jwt-token/src/main/java/com/jwt/token/JwtApplication.java b/ware-jwt-token/src/main/java/com/jwt/token/JwtApplication.java
new file mode 100644
index 0000000..eb03f79
--- /dev/null
+++ b/ware-jwt-token/src/main/java/com/jwt/token/JwtApplication.java
@@ -0,0 +1,11 @@
+package com.jwt.token;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class JwtApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(JwtApplication.class,args) ;
+ }
+}
diff --git a/ware-jwt-token/src/main/java/com/jwt/token/config/JwtConfig.java b/ware-jwt-token/src/main/java/com/jwt/token/config/JwtConfig.java
new file mode 100644
index 0000000..54c82ea
--- /dev/null
+++ b/ware-jwt-token/src/main/java/com/jwt/token/config/JwtConfig.java
@@ -0,0 +1,66 @@
+package com.jwt.token.config;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+import java.util.Date;
+
+@ConfigurationProperties(prefix = "config.jwt")
+@Component
+public class JwtConfig {
+ /*
+ * 根据身份ID标识,生成Token
+ */
+ public String getToken (String identityId){
+ Date nowDate = new Date();
+ //过期时间
+ Date expireDate = new Date(nowDate.getTime() + expire * 1000);
+ return Jwts.builder()
+ .setHeaderParam("typ", "JWT")
+ .setSubject(identityId)
+ .setIssuedAt(nowDate)
+ .setExpiration(expireDate)
+ .signWith(SignatureAlgorithm.HS512, secret)
+ .compact();
+ }
+ /*
+ * 获取 Token 中注册信息
+ */
+ public Claims getTokenClaim (String token) {
+ try {
+ return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
+ }catch (Exception e){
+ e.printStackTrace();
+ return null;
+ }
+ }
+ /*
+ * Token 是否过期验证
+ */
+ public boolean isTokenExpired (Date expirationTime) {
+ return expirationTime.before(new Date());
+ }
+ private String secret;
+ private long expire;
+ private String header;
+ public String getSecret() {
+ return secret;
+ }
+ public void setSecret(String secret) {
+ this.secret = secret;
+ }
+ public long getExpire() {
+ return expire;
+ }
+ public void setExpire(long expire) {
+ this.expire = expire;
+ }
+ public String getHeader() {
+ return header;
+ }
+ public void setHeader(String header) {
+ this.header = header;
+ }
+}
diff --git a/ware-jwt-token/src/main/java/com/jwt/token/config/WebConfig.java b/ware-jwt-token/src/main/java/com/jwt/token/config/WebConfig.java
new file mode 100644
index 0000000..27e6e20
--- /dev/null
+++ b/ware-jwt-token/src/main/java/com/jwt/token/config/WebConfig.java
@@ -0,0 +1,20 @@
+package com.jwt.token.config;
+
+import com.jwt.token.interceptor.TokenInterceptor;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import javax.annotation.Resource;
+
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+ /**
+ * 拦截器注册
+ */
+ @Resource
+ private TokenInterceptor tokenInterceptor ;
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(tokenInterceptor).addPathPatterns("/**");
+ }
+}
diff --git a/ware-jwt-token/src/main/java/com/jwt/token/controller/TokenController.java b/ware-jwt-token/src/main/java/com/jwt/token/controller/TokenController.java
new file mode 100644
index 0000000..4091d76
--- /dev/null
+++ b/ware-jwt-token/src/main/java/com/jwt/token/controller/TokenController.java
@@ -0,0 +1,44 @@
+package com.jwt.token.controller;
+
+import com.jwt.token.config.JwtConfig;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+public class TokenController {
+ @Resource
+ private JwtConfig jwtConfig ;
+ /*
+ * 返参格式
+ * {
+ * "userName": "ID123",
+ * "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.
+ * eyJzdWIiOiJJRDEyM3B3MTIzIiwiaWF0Ijox.
+ * SqqaZfG_g2OMijyN5eG0bPmkIQaqMRFlUvny"
+ * }
+ */
+ // 拦截器直接放行,返回Token
+ @PostMapping("/login")
+ public Map login (@RequestParam("userName") String userName,
+ @RequestParam("passWord") String passWord){
+ Map result = new HashMap<>() ;
+ // 省略数据源校验
+ String token = jwtConfig.getToken(userName+passWord) ;
+ if (!StringUtils.isEmpty(token)) {
+ result.put("token",token) ;
+ }
+ result.put("userName",userName) ;
+ return result ;
+ }
+ // 需要 Token 验证的接口
+ @PostMapping("/info")
+ public String info (){
+ return "info" ;
+ }
+}
diff --git a/ware-jwt-token/src/main/java/com/jwt/token/interceptor/TokenInterceptor.java b/ware-jwt-token/src/main/java/com/jwt/token/interceptor/TokenInterceptor.java
new file mode 100644
index 0000000..58f6664
--- /dev/null
+++ b/ware-jwt-token/src/main/java/com/jwt/token/interceptor/TokenInterceptor.java
@@ -0,0 +1,44 @@
+package com.jwt.token.interceptor;
+
+import com.jwt.token.config.JwtConfig;
+import io.jsonwebtoken.Claims;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Token 拦截器
+ */
+@Component
+public class TokenInterceptor extends HandlerInterceptorAdapter {
+ @Resource
+ private JwtConfig jwtConfig ;
+ @Override
+ public boolean preHandle(HttpServletRequest request,
+ HttpServletResponse response,
+ Object handler) throws Exception {
+ // 地址过滤
+ String uri = request.getRequestURI() ;
+ if (uri.contains("/login")){
+ return true ;
+ }
+ // Token 验证
+ String token = request.getHeader(jwtConfig.getHeader());
+ if(StringUtils.isEmpty(token)){
+ token = request.getParameter(jwtConfig.getHeader());
+ }
+ if(StringUtils.isEmpty(token)){
+ throw new Exception(jwtConfig.getHeader()+ "不能为空");
+ }
+ Claims claims = jwtConfig.getTokenClaim(token);
+ if(claims == null || jwtConfig.isTokenExpired(claims.getExpiration())){
+ throw new Exception(jwtConfig.getHeader() + "失效,请重新登录");
+ }
+ //设置 identityId 用户身份ID
+ request.setAttribute("identityId", claims.getSubject());
+ return true;
+ }
+}
diff --git a/ware-jwt-token/src/main/resources/application.yml b/ware-jwt-token/src/main/resources/application.yml
new file mode 100644
index 0000000..5816469
--- /dev/null
+++ b/ware-jwt-token/src/main/resources/application.yml
@@ -0,0 +1,13 @@
+server:
+ port: 7009
+spring:
+ application:
+ name: ware-jwt-token
+config:
+ jwt:
+ # 加密密钥
+ secret: iwqjhda8232bjgh432[cicada-smile]
+ # token有效时长
+ expire: 3600
+ # header 名称
+ header: token
\ No newline at end of file