前言
案例整合了Spring boot、Spring Cloud alibaba、Gateway、Nacos discovery、Nacos config、openFeign、JWT、Vue3、Router、Axios等;通过JWT和登录、查询(带用户信息)接口,验证了上述工具以及鉴权功能。
1、若无公共模块,先添加公共模块
1.1、创建模块:common-service
1.2、修改父项的pom文件
1.2.1、给springCloud父项添加子模块
1.2.2、添加common-service的全局依赖
<dependencies> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.hqyj</groupId> <artifactId>common-service</artifactId> <version>0.0.1-SNAPSHOT</version> <scope>compile</scope> </dependency> </dependencies>
1.3、修改common-service模块的pom文件
将pom文件中的标签和标签中的内容删除
注意事项:
这里不继承父项,因为要在父项添加common-service的全局依赖,要是继承了父项的话会清理打包会报错
1.4、添加依赖
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency>
1.5、添加dto
/** * @author kelvin * @Date 2023/5/16 - 9:58 */ import lombok.Data; /** * 统一返回类 * @param <T> */ @Data public class ResultDTO<T> { /** * 状态码 */ private int code = 200; /** * 提示信息 */ private String message = "成功!"; /** * 数据 */ private T data; /** * 无参构造 */ public ResultDTO(){} /** * 有参构造 * 参数:data * @param data */ public ResultDTO(T data){ this.data = data; } /** * 有参构造 * 自定义状态码、返回信息、数据 * @param code * @param message * @param data */ public ResultDTO(int code,String message,T data){ this.message = message; this.code = code; this.data = data; } }
import lombok.Data; /** * @author kelvin * @Date 2023/6/8 - 10:03 */ @Data public class TokenDTO { private String token; }
1.6、添加entity实体类
import lombok.Data; /** * @author kelvin * @Date 2023/6/8 - 9:37 */ @Data public class UserInfo { private String userId; private String userPassword; private String userAccount; }
1.7、创建http目录,添加以下文件
import com.xxxx.commonservice.dto.ResultDTO; /** * @author kelvin * @Date 2023/5/18 - 11:13 */ public class HttpResultGenerator { //正常返回时调用方法 public static ResultDTO success(HttpStatusEnum httpStatusEnum, Object data) { return new ResultDTO(httpStatusEnum.getCode() , httpStatusEnum.getMessage() , data); } //失败时调用方法(入参是异常枚举) public static ResultDTO fail(HttpStatusEnum httpStatusEnum) { return new ResultDTO(httpStatusEnum.getCode() , httpStatusEnum.getMessage() , null); } //失败时调用方法(提供给GlobalExceptionHandler类使用) public static ResultDTO fail(int code , String message) { return new ResultDTO(code , message , null); } }
/** * Http状态码 * @author kelvin * @Date 2023/5/18 - 10:56 */ public enum HttpStatusEnum implements HttpStatusInfoInterface{ //定义状态枚举值 SUCCESS(200 , "成功!"), NO_AUTHORITY(300,"暂无权限!"), BODY_NOT_MATCH(400 , "数据格式不匹配!"), NOT_FOUND(404 , "访问资源不存在!"), INTERNAM_SERVER_ERROR(500 , "服务器内部错误!"), SERVER_BUSY(503 , "服务器正忙,请稍后再试!"), REQUEST_METHOD_SUPPORT_ERROR(10001 , "当前请求方法不支持!"), REQUEST_DATA_NULL(10002 , "当前请求参数为空!"), USER_NOT_EXISTS(10003 , "该用户不存在!"), USER_INVALID(10004 , "当前登录信息已失效,请重新登录!"), PASSWORD_ERROR(10005 , "密码错误!"), USER_NAME_LOCK(10006 , "该账号已被锁定!"); //状态码 private int code; //提示信息 private String message; //构造方法 HttpStatusEnum(int code , String message) { this.code = code; this.message = message; } @Override public int getCode() { return this.code; } @Override public String getMessage() { return this.message; } }
/** * Http状态信息接口 * @author kelvin * @Date 2023/5/18 - 10:53 */ public interface HttpStatusInfoInterface { int getCode(); String getMessage(); }
2、添加模块
authority-service
2.1、添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </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.4.0</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2021.0.4.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2.2、修改配置文件
这里是在nacos 配置中心添加配置文件 或者 application.yml文件
server: port: 7777 spring: application: name: authority-service cloud: nacos: discovery: server-addr: localhost:8848 #Nacos server 的地址 config: jwt: # 加密密钥 secret: tigerkey # token有效时长 expire: 3600 # header 名称 header: token
2.3、新建config包,在包里新建JwtConfig
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.Date; @Component @ConfigurationProperties(prefix = "config.jwt") @Data public class JwtConfig { /** * 密钥 */ private String secret; /** * 过期时间 */ private Long expire; /** * 头部 */ private String header; /** * 生成token * @param subject * @return */ public String createToken(String subject){ Date nowDate = new Date(); Date expireDate = new Date(nowDate.getTime() + expire * 1000); return Jwts.builder() .setHeaderParam("typ","JWT") .setSubject(subject) .setIssuedAt(nowDate) .setExpiration(expireDate) .signWith(SignatureAlgorithm.HS512,secret) .compact(); } /** * 获取token中的注册信息 * @param token * @return */ public Claims getTokenClaim(String token){ try{ return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); }catch (Exception e){ return null; } } /** * 验证token是否过期 * @param expirationTime * @return */ public boolean isTokenExpired(Date expirationTime){ if(null == expirationTime){ return true; }else{ return expirationTime.before(new Date()); } } /** * 获取token的失效时间 * @param token * @return */ public Date getExpirationDateFromToken(String token){ Claims tokenClaim = this.getTokenClaim(token); if(tokenClaim == null){ return null; }else{ return this.getTokenClaim(token).getExpiration(); } } /** * 获取token中的用户名 * @param token * @return */ public String getUserNameFromToken(String token){ return this.getTokenClaim(token).getSubject(); } /** * 获取token中发布时间 * @param token * @return */ public Date getIssuedDateFromToken(String token){ return this.getTokenClaim(token).getIssuedAt(); } }