SpringCloud微服务项目实战 - 2.App登录及网关
如果你追求一个局部的更好甚至完美,你有可能花费巨大的资源和时间;
从总体上看,这往往意味着总体的浪费和失败,这是传说中的“打赢了战役打输了战争”。
系列文章目录
- 项目搭建
- App登录及网关
- App文章
- 自媒体平台(博主后台)
- 自媒体文章审核
- 延迟任务
- kafka及文章上下架
- App端文章搜索
- 后台系统管理
- Long类型精度丢失问题
- 定时计算热点文章(xxl-Job)
- 热点文章-实时计算(kafkaStream)
- 项目部署_持续集成(Jenkins)
文章目录
- 系列文章目录
- 一、App登录
- 1. 需求分析
- 2. 表结构分析
- ⑴. 导入数据库
- ⑵. 库表
- ⑶. 用户表(登录)
- ⑷. 实体类
- 3. 手动加密(md5+随机字符串)
- 4. 运营端微服务搭建
- ⑴. 创建模块
- ⑵. 引导类
- ⑶. 微服务配置文件
- ⑷. 日志配置文件
- ⑸. Nacos配置文件
- ⑹. 微服务标准包结构
- 5. 接口定义
- ⑴. 接口返回类分析
- ①. HttpCode枚举
- ②. 通用的结果返回类
- ③. 上面的返回类测试
- ④. 分页返回类
- ⑵. 实体类
- ⑶. Controller
- ⑷. Mapper
- ⑸. service
- ⑹. 实现类Impl
- ⑺. Controller
- 二、接口测试工具
- 1. Postman
- 2. Swagger
- ⑴. 配置
- ①. 引入依赖
- ②. 配置类
- ③. 自动配置
- ⑵. 注解
- ①. 常用注解
- ②. 接口注解
- ③. 参数注解
- ④. 在线API文档
- 3. Knife4j
- ⑴. 配置
- ①. 引入依赖
- ②. 配置类
- ③. 自动配置
- ⑵. 文档(可下载离线文档)
- 三、App网关
- 1. gateway网关微服务
- ⑴. 服务工程结构
- ⑵. 配置
- ①. 导入依赖
- ②. 引导类
- ③. 配置文件
- ④. nacos配置
- ⑶. 测试
- 2. 认证过滤器
- ⑴. 思路分析
- ⑵. 全局过滤器
- ⑶. 断点调试
- 四、App前端项目集成
- 1. nginx包
- 2. 前端项目
- 3. 配置nginx.conf文件1
- 4. 配置nginx.conf文件2
- 5. 重新加载nginx
- 6. 运行测试
一、App登录
1. 需求分析
- 登录: 登录后的用户权限较大,可以查看,也可以操作(点赞,关注,评论)
- 不登录,先看看: 游客只有查看的权限
2. 表结构分析
⑴. 导入数据库
sql文件链接:https://pan.baidu.com/s/11ITsQZQkR0Yl20lT10omwQ?pwd=abcd
⑵. 库表
关于app端用户相关的内容较多,可以单独设置一个库leadnews_user
表名称 | 说明 |
---|---|
ap_user | APP用户信息表 |
ap_user_fan | APP用户粉丝信息表 |
ap_user_follow | APP用户关注信息表 |
ap_user_realname | APP实名认证信息表 |
⑶. 用户表(登录)
登录需要用到的是 ap_user
表,表结构如下:
DDL文件:
CREATE TABLE `ap_user` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`salt` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '密码、通信等加密盐',`name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户名',`password` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '密码,md5加密',`phone` varchar(11) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手机号',`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '头像',`sex` tinyint(1) unsigned DEFAULT NULL COMMENT '0 男\r\n 1 女\r\n 2 未知',`is_certification` tinyint(1) unsigned DEFAULT NULL COMMENT '0 未\r\n 1 是',`is_identity_authentication` tinyint(1) DEFAULT NULL COMMENT '是否身份认证',`status` tinyint(1) unsigned DEFAULT NULL COMMENT '0正常\r\n 1锁定',`flag` tinyint(1) unsigned DEFAULT NULL COMMENT '0 普通用户\r\n 1 自媒体人\r\n 2 大V',`created_time` datetime DEFAULT NULL COMMENT '注册时间',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='APP用户信息表';
tinyint类型: 占1个字节,不指定unsigned(非负数),值范围(-128,127),指定了unsigned,值范围(0,255)
tinyint 通常表示小范围的数值,或者表示true或false,通常值为0表示false,值为1表示true
⑷. 实体类
新建 src/main/java/com/heima/model/user/pojos/ApUser.java
文件(app_user表对应的实体类):
/*** <p>* APP用户信息表* </p>** @author itheima*/
@Data
@TableName("ap_user")
public class ApUser implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.AUTO)private Integer id;/*** 密码、通信等加密盐*/@TableField("salt")private String salt;/*** 用户名*/@TableField("name")private String name;/*** 密码,md5加密*/@TableField("password")private String password;/*** 手机号*/@TableField("phone")private String phone;/*** 头像*/@TableField("image")private String image;/*** 0 男1 女2 未知*/@TableField("sex")private Boolean sex;/*** 0 未1 是*/@TableField("is_certification")private Boolean certification;/*** 是否身份认证*/@TableField("is_identity_authentication")private Boolean identityAuthentication;/*** 0正常1锁定*/@TableField("status")private Boolean status;/*** 0 普通用户1 自媒体人2 大V*/@TableField("flag")private Short flag;/*** 注册时间*/@TableField("created_time")private Date createdTime;}
3. 手动加密(md5+随机字符串)
md5是不可逆加密,md5相同的密码每次加密都一样,不太安全。在md5的基础上手动加盐(salt)处理
注册(生成盐)
登录(使用盐来配合验证)
4. 运营端微服务搭建
⑴. 创建模块
⑵. 引导类
新建 src/main/java/com/heima/user/UserApplication.java
文件:
@SpringBootApplication
@EnableDiscoveryClient // 集成当前的注册中心
@MapperScan("com.heima.user.mapper") // 集成myBatisPlus 扫描mapper
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class,args);}
}
⑶. 微服务配置文件
新建 heima-leadnews-service/heima-leadnews-user/src/main/resources/bootstrap.yml
文件:
server:port: 51801
spring:application:name: leadnews-usercloud:nacos:discovery:server-addr: 192.168.200.130:8848config:server-addr: 192.168.200.130:8848file-extension: yml
⑷. 日志配置文件
新建 heima-leadnews-service/heima-leadnews-user/src/main/resources/logback.xml
文件:
<?xml version="1.0" encoding="UTF-8"?><configuration><!--定义日志文件的存储地址,使用绝对路径--><property name="LOG_HOME" value="e:/logs"/><!-- Console 输出设置 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern><charset>utf8</charset></encoder></appender><!-- 按照每天生成日志文件 --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名--><fileNamePattern>${LOG_HOME}/leadnews.%d{yyyy-MM-dd}.log</fileNamePattern></rollingPolicy><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><!-- 异步输出 --><appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"><!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --><discardingThreshold>0</discardingThreshold><!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --><queueSize>512</queueSize><!-- 添加附加的appender,最多只能添加一个 --><appender-ref ref="FILE"/></appender><logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="DEBUG" additivity="false"><appender-ref ref="CONSOLE"/></logger><logger name="org.springframework.boot" level="debug"/><root level="info"><!--<appender-ref ref="ASYNC"/>--><appender-ref ref="FILE"/><appender-ref ref="CONSOLE"/></root>
</configuration>
⑸. Nacos配置文件
spring:redis:host: 192.168.200.130password: leadnewsport: 6379datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/leadnews_user?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: 123456
# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:mapper-locations: classpath*:mapper/*.xml# 设置别名包扫描路径,通过该属性可以给包中的类注册别名type-aliases-package: com.heima.model.user.pojos
⑹. 微服务标准包结构
5. 接口定义
⑴. 接口返回类分析
①. HttpCode枚举
查看 com/heima/model/common/enums/AppHttpCodeEnum.java
文件:
public enum AppHttpCodeEnum {// 成功段固定为200SUCCESS(200,"操作成功"),// 登录段1~50NEED_LOGIN(1,"需要登录后操作"),LOGIN_PASSWORD_ERROR(2,"密码错误"),// TOKEN50~100TOKEN_INVALID(50,"无效的TOKEN"),TOKEN_EXPIRE(51,"TOKEN已过期"),TOKEN_REQUIRE(52,"TOKEN是必须的"),// SIGN验签 100~120SIGN_INVALID(100,"无效的SIGN"),SIG_TIMEOUT(101,"SIGN已过期"),// 参数错误 500~1000PARAM_REQUIRE(500,"缺少参数"),PARAM_INVALID(501,"无效参数"),PARAM_IMAGE_FORMAT_ERROR(502,"图片格式有误"),SERVER_ERROR(503,"服务器内部错误"),// 数据错误 1000~2000DATA_EXIST(1000,"数据已经存在"),AP_USER_DATA_NOT_EXIST(1001,"ApUser数据不存在"),DATA_NOT_EXIST(1002,"数据不存在"),// 数据错误 3000~3500NO_OPERATOR_AUTH(3000,"无权限操作"),NEED_ADMIND(3001,"需要管理员权限");int code;String errorMessage;AppHttpCodeEnum(int code, String errorMessage){this.code = code;this.errorMessage = errorMessage;}public int getCode() {return code;}public String getErrorMessage() {return errorMessage;}
}
②. 通用的结果返回类
查看 com/heima/model/common/dtos/PageResponseResult.java
文件:
/*** 通用的结果返回类* @param <T>*/
public class ResponseResult<T> implements Serializable {private String host;private Integer code;private String errorMessage;private T data;public ResponseResult() {this.code = 200;}public ResponseResult(Integer code, T data) {this.code = code;this.data = data;}public ResponseResult(Integer code, String msg, T data) {this.code = code;this.errorMessage = msg;this.data = data;}public ResponseResult(Integer code, String msg) {this.code = code;this.errorMessage = msg;}public static ResponseResult errorResult(int code, String msg) {ResponseResult result = new ResponseResult();return result.error(code, msg);}public static ResponseResult okResult(int code, String msg) {ResponseResult result = new ResponseResult();return result.ok(code, null, msg);}public static ResponseResult okResult(Object data) {ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS, AppHttpCodeEnum.SUCCESS.getErrorMessage());if(data!=null) {result.setData(data);}return result;}public static ResponseResult errorResult(AppHttpCodeEnum enums){return setAppHttpCodeEnum(enums,enums.getErrorMessage());}public static ResponseResult errorResult(AppHttpCodeEnum enums, String errorMessage){return setAppHttpCodeEnum(enums,errorMessage);}public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums){return okResult(enums.getCode(),enums.getErrorMessage());}private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums, String errorMessage){return okResult(enums.getCode(),errorMessage);}public ResponseResult<?> error(Integer code, String msg) {this.code = code;this.errorMessage = msg;return this;}public ResponseResult<?> ok(Integer code, T data) {this.code = code;this.data = data;return this;}public ResponseResult<?> ok(Integer code, T data, String msg) {this.code = code;this.data = data;this.errorMessage = msg;return this;}public ResponseResult<?> ok(T data) {this.data = data;return this;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getErrorMessage() {return errorMessage;}public void setErrorMessage(String errorMessage) {this.errorMessage = errorMessage;}public T getData() {return data;}public void setData(T data) {this.data = data;}public String getHost() {return host;}public void setHost(String host) {this.host = host;}// 测试类public static void main(String[] args) {//前置/* AppHttpCodeEnum success = AppHttpCodeEnum.SUCCESS;System.out.println(success.getCode());System.out.println(success.getErrorMessage());*///查询一个对象/*Map map = new HashMap();map.put("name","zhangsan");map.put("age",18);ResponseResult result = ResponseResult.okResult(map);System.out.println(JSON.toJSONString(result));*///新增,修改,删除 在项目中统一返回成功即可/*ResponseResult result = ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);System.out.println(JSON.toJSONString(result));*///根据不用的业务返回不同的提示信息 比如:当前操作需要登录、参数错误/*ResponseResult result = ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN,"自定义提示信息");System.out.println(JSON.toJSONString(result));*///查询分页信息PageResponseResult responseResult = new PageResponseResult(1,5,50);List list = new ArrayList();list.add("itcast");list.add("itheima");responseResult.setData(list);System.out.println(JSON.toJSONString(responseResult));}}
③. 上面的返回类测试
④. 分页返回类
查看 com/heima/model/common/dtos/PageResponseResult.java
文件:
public class PageResponseResult extends ResponseResult implements Serializable {private Integer currentPage;private Integer size;private Integer total;public PageResponseResult(Integer currentPage, Integer size, Integer total) {this.currentPage = currentPage;this.size = size;this.total = total;}public PageResponseResult() {}public int getCurrentPage() {return currentPage;}public void setCurrentPage(int currentPage) {this.currentPage = currentPage;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}public int getTotal() {return total;}public void setTotal(int total) {this.total = total;}
}
⑵. 实体类
新建 heima-leadnews-model/src/main/java/com/heima/model/user/dtos/LoginDto.java
文件:
@Data
public class LoginDto {/*** 手机号*/@ApiModelProperty(value = "手机号",required = true)private String phone;/*** 密码*/@ApiModelProperty(value = "密码",required = true)private String password;
}
⑶. Controller
新建 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/controller/v1/ApUserLoginController.java
文件:
@RestController
@RequestMapping("/api/v1/login")
public class ApUserLoginController {@PostMapping("/login_auth")public ResponseResult login(@RequestBody LoginDto dto) {return null;}
}
⑷. Mapper
新建 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/mapper/ApUserMapper.java
文件:
@Mapper
public interface ApUserMapper extends BaseMapper<ApUser> {}
⑸. service
新建 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/service/ApUserService.java
文件:
public interface ApUserService extends IService<ApUser>{/*** app端登录* @param dto* @return*/public ResponseResult login(LoginDto dto);}
⑹. 实现类Impl
- 用户输入了用户名和密码进行登录,校验成功后返回jwt(基于当前用户的id生成)
- 用户游客登录,生成jwt返回(基于默认值0生成)
新建 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/service/impl/ApUserServiceImpl.java
文件:
@Service
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {@Overridepublic ResponseResult login(LoginDto dto) {//1.正常登录(手机号+密码登录)if (!StringUtils.isBlank(dto.getPhone()) && !StringUtils.isBlank(dto.getPassword())) {//1.1查询用户ApUser apUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, dto.getPhone()));if (apUser == null) {return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"用户不存在");}//1.2 比对密码String salt = apUser.getSalt();String pswd = dto.getPassword();pswd = DigestUtils.md5DigestAsHex((pswd + salt).getBytes());if (!pswd.equals(apUser.getPassword())) {return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);}//1.3 返回数据 jwtMap<String, Object> map = new HashMap<>();map.put("token", AppJwtUtil.getToken(apUser.getId().longValue()));apUser.setSalt("");apUser.setPassword("");map.put("user", apUser);return ResponseResult.okResult(map);} else {//2.游客 同样返回token id = 0Map<String, Object> map = new HashMap<>();map.put("token", AppJwtUtil.getToken(0l));return ResponseResult.okResult(map);}}
}
⑺. Controller
编辑 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/controller/v1/ApUserLoginController.java
文件:
@RestController
@RequestMapping("/api/v1/login")
@Api(value = "app端用户登录",tags = "app端用户登录")
public class ApUserLoginController {@Autowiredprivate ApUserService apUserService;@PostMapping("/login_auth")@ApiOperation("用户登录")public ResponseResult login(@RequestBody LoginDto dto){return apUserService.login(dto);}
}
二、接口测试工具
1. Postman
测试 账号错误
、密码错误
、游客登录
、用户登录
返回信息是否正确
2. Swagger
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务(https://swagger.io/)。
⑴. 配置
①. 引入依赖
在 heima-leadnews-model
和 heima-leadnews-common
模块中引入该依赖
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId></dependency>
②. 配置类
新建 heima-leadnews-common/src/main/java/com/heima/common/swagger/SwaggerConfiguration.java
文件:
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {@Beanpublic Docket buildDocket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(buildApiInfo()).select()// 要扫描的API(Controller)基础包.apis(RequestHandlerSelectors.basePackage("com.heima")).paths(PathSelectors.any()).build();}private ApiInfo buildApiInfo() {Contact contact = new Contact("后海","","");return new ApiInfoBuilder().title("新闻头条-平台管理API文档").description("新闻头条后台api").contact(contact).version("1.0.0").build();}
}
③. 自动配置
编辑 heima-leadnews-common/src/main/resources/META-INF/spring.factories
文件:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.heima.common.exception.ExceptionCatch,\com.heima.common.swagger.SwaggerConfiguration
⑵. 注解
①. 常用注解
在Java类中添加Swagger的注解即可生成Swagger接口文档,常用Swagger注解如下:
- @Api:修饰整个类,描述Controller的作用
- @ApiOperation:描述一个类的一个方法,或者说一个接口
- @ApiParam:单个参数的描述信息
- @ApiModel:用对象来接收参数
- @ApiModelProperty:用对象接收参数时,描述对象的一个字段
- @ApiResponse:HTTP响应其中1个描述
- @ApiResponses:HTTP响应整体描述
- @ApiIgnore:使用该注解忽略这个API
- @ApiError :发生错误返回的信息
- @ApiImplicitParam:一个请求参数
- @ApiImplicitParams:多个请求参数的描述信息
@ApiImplicitParam属性:
属性 | 取值 | 作用 |
---|---|---|
paramType | 查询参数类型 | |
path | 以地址的形式提交数据 | |
query | 直接跟参数完成自动映射赋值 | |
body | 以流的形式提交 仅支持POST | |
header | 参数在request headers 里边提交 | |
form | 以form表单的形式提交 仅支持POST | |
dataType | 参数的数据类型 只作为标志说明,并没有实际验证 | |
Long | ||
String | ||
name | 接收参数名 | |
value | 接收参数的意义描述 | |
required | 参数是否必填 | |
true | 必填 | |
false | 非必填 | |
defaultValue | 默认值 |
②. 接口注解
编辑 heima-leadnews-service/heima-leadnews-user/src/main/java/com/heima/user/controller/v1/ApUserLoginController.java
文件:
@RestController
@RequestMapping("/api/v1/login")
@Api(value = "app端用户登录", tags = "ap_user", description = "app端用户登录API")
public class ApUserLoginController {@Autowiredprivate ApUserService apUserService;@PostMapping("/login_auth")@ApiOperation("用户登录")public ResponseResult login(@RequestBody LoginDto dto){return apUserService.login(dto);}
}
③. 参数注解
编辑 heima-leadnews-model/src/main/java/com/heima/model/user/dtos/LoginDto.java
文件:
@Data
public class LoginDto {/*** 手机号*/@ApiModelProperty(value="手机号",required = true)private String phone;/*** 密码*/@ApiModelProperty(value="密码",required = true)private String password;
}
④. 在线API文档
启动user微服务,访问地址:http://localhost:51801/swagger-ui.html
3. Knife4j
knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名kni4j是希望它能像一把匕首一样小巧,轻量,并且功能强悍!(https://doc.xiaominfo.com/)
⑴. 配置
①. 引入依赖
编辑 heima-leadnews-common/pom.xml
文件:
<!--knife4j接口文档--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId></dependency>
②. 配置类
新建 heima-leadnews-common/src/main/java/com/heima/common/swagger/Swagger2Configuration.java
文件:
@Configuration
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
public class Swagger2Configuration {@Bean(value = "defaultApi2")public Docket defaultApi2() {Docket docket=new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())//分组名称.groupName("1.0").select()//这里指定Controller扫描包路径.apis(RequestHandlerSelectors.basePackage("com.heima")).paths(PathSelectors.any()).build();return docket;}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("新闻头条API文档").description("新闻头条API文档").version("1.0").build();}
}
以上有两个注解需要特别说明:
注解 | 说明 |
---|---|
@EnableSwagger2
|
该注解是Springfox-swagger框架提供的使用Swagger注解,该注解必须加 |
@EnableKnife4j
|
该注解是knife4j 提供的增强注解,Ui提供了例如动态参数、参数过滤、接口排序等增强功能,如果你想使用这些增强功能就必须加该注解,否则可以不用加
|
③. 自动配置
编辑 heima-leadnews-common/src/main/resources/META-INF/spring.factories
文件:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.heima.common.exception.ExceptionCatch,\com.heima.common.swagger.SwaggerConfiguration,\com.heima.common.swagger.Swagger2Configuration
⑵. 文档(可下载离线文档)
接口文档: http://localhost:51801/doc.htm
三、App网关
1. gateway网关微服务
⑴. 服务工程结构
- heima-leadnews-gateway 网关
- heima-leadnews-admin-gateway 管理平台
- heima-leadnews-wemedia-gateway 用户自媒体平台
- heima-leadnews-app-gateway 用户移动APP
⑵. 配置
①. 导入依赖
新建 heima-leadnews-gateway/pom.xml
文件:
<dependencies><!--gateway的staeter--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--nacos的注册中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--nacos的配置中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--jwt解析jar包--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency></dependencies>
②. 引导类
新建 heima-leadnews-gateway/heima-leadnews-app-gateway/src/main/java/com/heima/app/gateway/AppGatewayApplication.java
文件:
@SpringBootApplication
@EnableDiscoveryClient //开启注册中心
public class AppGatewayApplication {public static void main(String[] args) {SpringApplication.run(AppGatewayApplication.class,args);}
}
③. 配置文件
编辑 heima-leadnews-gateway/heima-leadnews-app-gateway/src/main/resources/bootstrap.yml
文件:
server:port: 51601
spring:application:name: leadnews-app-gatewaycloud:nacos:discovery:server-addr: 192.168.200.130:8848config:server-addr: 192.168.200.130:8848file-extension: yml
④. nacos配置
nocos地址: http://192.168.200.130:8848/nacos
spring:cloud:gateway:globalcors:add-to-simple-url-handler-mapping: truecorsConfigurations:'[/**]':allowedHeaders: "*"allowedOrigins: "*"allowedMethods:- GET- POST- DELETE- PUT- OPTIONroutes:# 平台管理- id: useruri: lb://leadnews-userpredicates:- Path=/user/**filters:- StripPrefix= 1
⑶. 测试
启动项目网关和用户两个服务,使用postman进行测试
网关后的请求地址: localhost:51601/user/api/v1/login/login_auth
2. 认证过滤器
⑴. 思路分析
- 用户进入网关开始登陆,网关过滤器进行判断,如果是登录,则路由到后台管理微服务进行登录
- 用户登录成功,后台管理微服务签发JWT TOKEN信息返回给用户
- 用户再次进入网关开始访问,网关过滤器接收用户携带的TOKEN
- 网关过滤器解析TOKEN ,判断是否有权限,如果有,则放行,如果没有则返回未认证错误
⑵. 全局过滤器
新建 heima-leadnews-gateway/heima-leadnews-app-gateway/src/main/java/com/heima/app/gateway/filter/AuthorizeFilter.java
文件:
@Component
@Slf4j
public class AuthorizeFilter implements Ordered, GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//1.获取request和response对象ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();//2.判断是否是登录if(request.getURI().getPath().contains("/login")){//放行return chain.filter(exchange);}//3.获取tokenString token = request.getHeaders().getFirst("token");//4.判断token是否存在if(StringUtils.isBlank(token)){response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//5.判断token是否有效try {Claims claimsBody = AppJwtUtil.getClaimsBody(token);//是否是过期int result = AppJwtUtil.verifyToken(claimsBody);if(result == 1 || result == 2){response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}}catch (Exception e){e.printStackTrace();response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//6.放行return chain.filter(exchange);}/*** 优先级设置 值越小 优先级越高* @return*/@Overridepublic int getOrder() {return 0;}
}
⑶. 断点调试
启动user服务,访问其他微服务,会提示需要认证才能访问,这个时候需要在heads中设置设置token才能正常访问。
四、App前端项目集成
- 通过nginx的反向代理功能访问后台的网关资源
- 通过nginx的静态服务器功能访问前端静态页面
1. nginx包
资源链接: https://pan.baidu.com/s/1gPfoG0FnLC3dIUjJhqlKSQ?pwd=abcd
解压包,运行nginx
2. 前端项目
资源链接: https://pan.baidu.com/s/1wqfxtQCj_aGqSZVxgADVTQ?pwd=abcd
解压包,记住前端项目存放路径
3. 配置nginx.conf文件1
(nginx包中)新建 D:\code\hm\leadnews\config\nginx-1.18.0\conf\leadnews.conf\heima-leadnews-app.conf
文件:
upstream heima-app-gateway{server localhost:51601; # 根据网关去做的请求
}server {listen 8801;location / {root D:/code/hm/leadnews/config/app-web/; # 访问前端静态资源index index.html;}location ~/app/(.*) {proxy_pass http://heima-app-gateway/$1;proxy_set_header HOST $host; # 不改变源请求头的值proxy_pass_request_body on; #开启获取请求体proxy_pass_request_headers on; #开启获取请求头proxy_set_header X-Real-IP $remote_addr; # 记录真实发出请求的客户端IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #记录代理信息}
}
4. 配置nginx.conf文件2
(nginx包中)编辑 D:\code\hm\leadnews\config\nginx-1.18.0\conf\leadnews.conf\nginx.conf
文件:
#user nobody;
worker_processes 1;events {worker_connections 1024;
}
http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;# 引入自定义配置文件include leadnews.conf/*.conf;
}
5. 重新加载nginx
# 重新加载nginx
nginx -s reload
6. 运行测试
前端地址: http://localhost:8801/
SpringCloud微服务项目实战 - 2.App登录及网关相关推荐
- SpringCloud微服务项目实战 - 5.自媒体文章审核
愤怒归根结底是为了达成目的的一种工具和手段,大声呵斥乃至拍桌子,目的都是通过震慑对方,进而使其听自己的话,因为他们也找不到更好的办法. 系列文章目录 项目搭建 App登录及网关 App文章 自媒体平台 ...
- SpringCloud微服务项目实战 - 6.延迟任务
我没有失约,我与春风共至,我与夏蝉共鸣,我与秋叶共舞,我与凛冬共至,唯独你背道而行! 系列文章目录 项目搭建 App登录及网关 App文章 自媒体平台(博主后台) 内容审核(自动) 延迟任务 - 精准 ...
- SpringCloud微服务架构实战库存管理与分布式文件系统
库存管理与分布式文件系统 在电商平台的库存管理系统设计中,将涉及商品和本地图库的管理,这里我们将使用另一种数据开发框架 MyBatis进行数据库访问方面的设计,还将实现与分布式文件系统的对接使用. 本 ...
- SpringCloud微服务架构实战:商家权限体系设计及开发
商家管理后台与sso设计 在本文的电商平台实例中,商家是这个平台的主角,商家管理后台是专门为这个主角提供的一个安全可靠的操作平台.在商家管理后台中,商家可以进行商品管理.订单管理.物流管理.会员管理. ...
- SpringCloud微服务架构实战:微服务治理
微服务治理 Spring Cloud 工具套件为微服务治理提供了全面的技术支持.这些治理工具主要包括服务的注册与发现.负载均衡管理.动态路由.服务降级和故障转移.链路跟踪.服务监控等.微服务治理的主要 ...
- 微服务 前台调用后台的慢的原因_20年IT农民工分享SpringCloud微服务架构实战文档...
前言 越来越多的企业使用 SpringCloud 实现微服务架构设计.我们可以看到这样一种现象:不管是全新开发,还是系统重构,大家似乎都在争先恐后地使用微服务.对于一个Java开发人员来说,学习微服务 ...
- springcloud微服务项目架构搭建第一天
springcloud微服务项目架构搭建第一天 (一).项目简介 1.准备工作:idea创建springboot模板 2.后台应该涉及的技术(后期可能会有删改) Spring Framework 容器 ...
- Spring Cloud Alibaba 大型微服务项目实战
作者介绍 程序员十三,多年一线开发经验,历任高级开发工程师.后端主程.技术部门主管等职位.同时也是开源项目的爱好者和贡献者.掘金优秀作者.CSDN 博客专家.实体图书作者.专栏作者.视频讲师. 小册介 ...
- 关于华为私有云部署若依springcloud微服务项目改造及部署
关于华为私有云部署若依springcloud微服务项目改造及部署 1.项目介绍 当前微服务项目主流的注册中心为阿里巴巴的nacos,但介于甲方要求使用华为的注册中心,所以在接下来讲解项目改造: 2 ...
最新文章
- 游击式(移动)开发的两种方式
- rpm安装两个mysql_MySQL通过rpm安装及其单机多实例部署
- 1027. 打印沙漏(20)
- SQL Cookbook—数字、日期
- 大数据_Flink_流式处理_简介_认识一下什么是BI中的ETL---Flink工作笔记0005
- RMAN备份与恢复资料
- uiactionsheet 代理_iOS UIActionSheet (点击事件笔记)
- TCP/IP - ARP的作用、RARP协议
- 二元函数对xy同时求导_《高等数学》微课视频“二元函数的全微分求积”录音...
- JAVA数组内存分析 面向对象 类和对象 创建对象的内存分析 成员变量 局部变量
- 基于双目深度估计的深度学习技术研究
- java set方法无法使用_Java setBounds无法与JPanel一起使用
- 清华大学尹成 怎么样
- 关于我的专业(niit软件工程方向)
- c语言300行代码大作业,C语言300行代码
- UX术语详解:任务流,用户流,流程图以及其它全新术语
- 如何用php农场项目,2020全新亲测php农场游戏源码-金币菇种植理财区块链源码 带商城系统...
- 2019 年科技趋势最全汇总!
- 牛客网Java编程题总结
- STM32程序烧录---TTL