Browse Source

🗃️ 通用部分、JWT工具类完成

pull/1/head
Yangkai.Shen 6 years ago
parent
commit
d4408ef28e
7 changed files with 440 additions and 0 deletions
  1. +131
    -0
      spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/common/ApiResponse.java
  2. +47
    -0
      spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/common/BaseException.java
  3. +32
    -0
      spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/common/IStatus.java
  4. +65
    -0
      spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/common/Status.java
  5. +31
    -0
      spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/config/JwtConfig.java
  6. +87
    -0
      spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/util/JwtUtil.java
  7. +47
    -0
      spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/util/ResponseUtil.java

+ 131
- 0
spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/common/ApiResponse.java View File

@@ -0,0 +1,131 @@
package com.xkcoding.rbac.security.common;

import lombok.Data;

import java.io.Serializable;

/**
* <p>
* 通用的 API 接口封装
* </p>
*
* @package: com.xkcoding.rbac.security.common
* @description: 通用的 API 接口封装
* @author: yangkai.shen
* @date: Created in 2018-12-07 14:55
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Data
public class ApiResponse implements Serializable {
private static final long serialVersionUID = 8993485788201922830L;

/**
* 状态码
*/
private Integer code;

/**
* 返回内容
*/
private String message;

/**
* 返回数据
*/
private Object data;

/**
* 无参构造函数
*/
private ApiResponse() {

}

/**
* 全参构造函数
*
* @param code 状态码
* @param message 返回内容
* @param data 返回数据
*/
private ApiResponse(Integer code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}

/**
* 构造一个自定义的API返回
*
* @param code 状态码
* @param message 返回内容
* @param data 返回数据
* @return ApiResponse
*/
public static ApiResponse of(Integer code, String message, Object data) {
return new ApiResponse(code, message, data);
}

/**
* 构造一个成功且不带数据的API返回
*
* @return ApiResponse
*/
public static ApiResponse ofSuccess() {
return ofSuccess(null);
}

/**
* 构造一个成功且带数据的API返回
*
* @param data 返回数据
* @return ApiResponse
*/
public static ApiResponse ofSuccess(Object data) {
return ofStatus(Status.SUCCESS, data);
}

/**
* 构造一个成功且自定义消息的API返回
*
* @param message 返回内容
* @return ApiResponse
*/
public static ApiResponse ofMessage(String message) {
return of(Status.SUCCESS.getCode(), message, null);
}

/**
* 构造一个有状态的API返回
*
* @param status 状态 {@link Status}
* @return ApiResponse
*/
public static ApiResponse ofStatus(Status status) {
return ofStatus(status, null);
}

/**
* 构造一个有状态且带数据的API返回
*
* @param status 状态 {@link IStatus}
* @param data 返回数据
* @return ApiResponse
*/
public static ApiResponse ofStatus(IStatus status, Object data) {
return of(status.getCode(), status.getMessage(), data);
}

/**
* 构造一个异常的API返回
*
* @param t 异常
* @param <T> {@link BaseException} 的子类
* @return ApiResponse
*/
public static <T extends BaseException> ApiResponse ofException(T t) {
return of(t.getCode(), t.getMessage(), t.getData());
}
}

+ 47
- 0
spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/common/BaseException.java View File

@@ -0,0 +1,47 @@
package com.xkcoding.rbac.security.common;

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
* <p>
* 异常基类
* </p>
*
* @package: com.xkcoding.rbac.security.common
* @description: 异常基类
* @author: yangkai.shen
* @date: Created in 2018-12-07 14:57
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class BaseException extends RuntimeException {
private Integer code;
private String message;
private Object data;

public BaseException(Status status) {
super(status.getMessage());
this.code = status.getCode();
this.message = status.getMessage();
}

public BaseException(Status status, Object data) {
this(status);
this.data = data;
}

public BaseException(Integer code, String message) {
super(message);
this.code = code;
this.message = message;
}

public BaseException(Integer code, String message, Object data) {
this(code, message);
this.data = data;
}
}

+ 32
- 0
spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/common/IStatus.java View File

@@ -0,0 +1,32 @@
package com.xkcoding.rbac.security.common;

/**
* <p>
* REST API 错误码接口
* </p>
*
* @package: com.xkcoding.rbac.security.common
* @description: REST API 错误码接口
* @author: yangkai.shen
* @date: Created in 2018-12-07 14:35
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
public interface IStatus {

/**
* 状态码
*
* @return 状态码
*/
Integer getCode();

/**
* 返回信息
*
* @return 返回信息
*/
String getMessage();

}

+ 65
- 0
spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/common/Status.java View File

@@ -0,0 +1,65 @@
package com.xkcoding.rbac.security.common;

import lombok.Getter;

/**
* <p>
* 通用状态码
* </p>
*
* @package: com.xkcoding.rbac.security.common
* @description: 通用状态码
* @author: yangkai.shen
* @date: Created in 2018-12-07 14:31
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Getter
public enum Status implements IStatus {
/**
* 操作成功
*/
SUCCESS(200, "操作成功"),
/**
* 操作异常
*/
ERROR(500, "操作异常"),

/**
* 退出成功
*/
LOGOUT(200, "退出成功");

/**
* 状态码
*/
private Integer code;

/**
* 返回信息
*/
private String message;

Status(Integer code, String message) {
this.code = code;
this.message = message;
}

public static Status fromCode(Integer code) {
Status[] statuses = Status.values();
for (Status status : statuses) {
if (status.getCode()
.equals(code)) {
return status;
}
}
return SUCCESS;
}

@Override
public String toString() {
return String.format(" Status:{code=%s, message=%s} ", getCode(), getMessage());
}

}

+ 31
- 0
spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/config/JwtConfig.java View File

@@ -0,0 +1,31 @@
package com.xkcoding.rbac.security.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
* <p>
* JWT 配置
* </p>
*
* @package: com.xkcoding.rbac.security.config
* @description: JWT 配置
* @author: yangkai.shen
* @date: Created in 2018-12-07 13:42
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@ConfigurationProperties(prefix = "jwt.config")
@Data
public class JwtConfig {
/**
* jwt 加密 key, 默认值:xkcoding.
*/
private String key = "xkcoding";

/**
* jwt 过期时间, 默认值:600000 {@code 10 分钟}.
*/
private Long ttl = 600000L;
}

+ 87
- 0
spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/util/JwtUtil.java View File

@@ -0,0 +1,87 @@
package com.xkcoding.rbac.security.util;

import cn.hutool.core.date.DateUtil;
import com.xkcoding.rbac.security.config.JwtConfig;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.Date;

/**
* <p>
* JWT 工具类
* </p>
*
* @package: com.xkcoding.rbac.security.util
* @description: JWT 工具类
* @author: yangkai.shen
* @date: Created in 2018-12-07 13:42
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@EnableConfigurationProperties(JwtConfig.class)
@Configuration
@Slf4j
public class JwtUtil {
private final JwtConfig jwtConfig;

@Autowired
public JwtUtil(JwtConfig jwtConfig) {
this.jwtConfig = jwtConfig;
}

/**
* 创建JWT
*
* @param id 用户id
* @param subject 用户名
* @param roles 用户角色
* @return JWT
*/
public String createJWT(String id, String subject, String roles) {
Date now = new Date();
JwtBuilder builder = Jwts.builder()
.setId(id)
.setSubject(subject)
.setIssuedAt(now)
.signWith(SignatureAlgorithm.HS256, jwtConfig.getKey())
.claim("roles", roles);
if (jwtConfig.getTtl() > 0) {
builder.setExpiration(DateUtil.offsetMillisecond(now, jwtConfig.getTtl()
.intValue()));
}
return builder.compact();
}

/**
* 解析JWT
*
* @param jwt JWT
* @return {@link Claims}
*/
public Claims parseJWT(String jwt) {
Claims claims = null;
try {
claims = Jwts.parser()
.setSigningKey(jwtConfig.getKey())
.parseClaimsJws(jwt)
.getBody();
} catch (ExpiredJwtException e) {
log.error("Token 已过期");
} catch (UnsupportedJwtException e) {
log.error("不支持的 Token");
} catch (MalformedJwtException e) {
log.error("Token 无效");
} catch (SignatureException e) {
log.error("无效的 Token 签名");
} catch (IllegalArgumentException e) {
log.error("Token 参数不存在");
}
return claims;
}

}

+ 47
- 0
spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/util/ResponseUtil.java View File

@@ -0,0 +1,47 @@
package com.xkcoding.rbac.security.util;

import cn.hutool.json.JSONUtil;
import com.xkcoding.rbac.security.common.ApiResponse;
import com.xkcoding.rbac.security.common.IStatus;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* <p>
* Response 通用工具类
* </p>
*
* @package: com.xkcoding.rbac.security.util
* @description: Response 通用工具类
* @author: yangkai.shen
* @date: Created in 2018-12-07 17:37
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Slf4j
public class ResponseUtil {

/**
* 往 response 写出 json
*
* @param response 响应
* @param status 状态
* @param data 返回数据
*/
public static void renderJson(HttpServletResponse response, IStatus status, Object data) {
try {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setContentType("application/json;charset=UTF-8");
response.setStatus(200);

response.getWriter()
.write(JSONUtil.toJsonStr(ApiResponse.ofStatus(status, data)));
} catch (IOException e) {
log.error("Response写出JSON异常,", e);
}
}
}

Loading…
Cancel
Save