【智慧出行项目介绍】一个基于javaweb的微服务项目

由于本人更偏向于后端开发,所以本项目的前端部分在此省略,涉及到的一些坑会在后续指出。

目录

一、技术栈

二、技术描述

三、运行环境

四、详细实现方案和技术讲解

1.基于Oauth2.0的分布式权限认证方案

1.1.整体方案

1.2.Oauth2.0的四种授权模式

1.3.通过RBAC模型动态分配资源

1.4.jwt格式的token

1.5.核心配置文件

2.redis缓存

2.1.谈谈一致性

2.2.一致性方案

2.3.Geo存储地理位置

2.4.HyperLogLog记录UV值

2.5.缓存临时数据

3.schedule定时清除

3.1.定时将redis库存刷入mysql

3.2.定时清除垃圾图片 

3.3.定时把redis中的UV值刷入mysql

3.4.定时更新热门城市top5

4.订单操作

4.1.谈一谈消息可靠性

4.2.实现流程图

4.3.创建订单

4.4.取消订单

4.5.支付订单

4.6.退款订单

5.第三方接口

5.1.支付宝沙箱

5.2.网易邮箱

5.3.腾讯云COS&SMS

6.日志模块

五、一些(很多)坑

5.1.gateway和springsecurity整合

5.2.feign远程调用403


一、技术栈

  1. 前端:Vue、ElementUI、Axios
  2. 后端:SpringCloud(Nacos、Seata、Feign)、SpringSecurity(Oauth2.0、Jwt)、Mybatis
  3. 第三方服务:腾讯云SMS、腾讯云COS、163邮箱、支付宝沙箱
  4. 中间件:MySQL、Redis、RabbitMQ
  5. 网关:Nginx、Gateway

二、技术描述

  • 后端使用SpringCloud搭建,划分为网关、用户、旅游、认证、消息五大服务,使用的相关组件为Nacos、Seata、Feign等。
  • 基于Oauth2.0协议,搭建UAA并使用SpringSecurity+Jwt实现分布式认证授权,采用RBAC模型动态分配资源列表。
  • 使用Redis缓存旅游景点等热点数据,合理利用HyperLogLog、Geo缓存网页UV值和城市、景点地理位置。
  • 使用SpringSchedule定时清除垃圾图片、刷新库存和UV值。使用SpringAOP+自定义注解记录相关操作日志。
  • 使用RabbitMQ实现订单延时取消,通过发布订阅模式异步处理订单的附加操作。通过token、本地消息表保证消息幂等性。
  • 整合多个第三方服务:腾讯云COS、腾讯云SMS、163邮箱、支付宝沙箱。
  • 使用Vue+ElementUI+Axios快速搭建前端页面。

三、运行环境

腾讯云CentOS 7.6(1核2G、2核4G)、jdk8、erlang2.2、gcc4.8.5

四、详细实现方案和技术讲解

1.基于Oauth2.0的分布式权限认证方案

1.1.整体方案

        什么是Oauth2.0?简单的讲,就是我们在A应用上可以直接用B应用的账号进行登录,避免了在A应用上再去单独注册一个账号,同时也可以通过授权码模式(后续会讲到)防止A应用直接获取到B应用的密码等,比较常见的例子就是我们可以在csdn上用qq、vx进行登录,qq和vx只需要提供给csdn用户id、头像这些不敏感的信息即可。但在此项目中其实A应用和B应用都是智慧出行这个应用,只是引用了Oauth2.0这个思想。 

        下图为智慧出行网站基于Oauth2.0的分布式认证授权方案,第一步,接入方(其实就是我们自己的网站)请求UAA;第二步,UAA内部进行用户密码、权限的判断和基于RBAC分配资源(后续讲到);第三步,UAA返回给client一个jwt(后续会讲到)格式的token;第四步,前端访问资源时需要在Headers里添加token进行访问;第五步,资源服务器内部进行token的解析,判断token是否被篡改和过期。

1.2.Oauth2.0的四种授权模式

        UAA(User Access authorization)是授权服务器,主要用于注册客户端(client)、验证用户身份、向用户发放令牌(token)和刷新令牌。Oauth2.0涉及到四种授权模式,接下来我们一一讲解:

简单模式

         这种模式client只需要向UAA请求token然后通过此token进行资源访问即可,但它本身已经失去了授权的意义,这种模式更适用于一种程序间内部调用的情景。

密码模式

        密码模式就比简单模式多了一个步骤,就是需要client携带用户名和密码请求token,但弊端就是我们的用户名和密码可能会因此泄露给client,假设一种情况,此时你需要在智慧出行网站上通过支付宝登录,但这个登录页面是智慧出行网站提供的,你会放心大胆地在这个页面上输入你的支付宝账号和密码吗?

隐式模式

        相比于密码模式,隐式模式在用户进行登录验证时,它会重定向到验证服务器,也就是我们用支付宝登录,那么就会redirect到支付宝的验证服务器,此时你就可以很放心地输入密码了,但缺点就是返回的token可能被盗取。在智慧出行网站中,我是采用了隐式模式模拟的第三方登录,为了防止token被盗取后篡改,我使用了jwt格式的token,jwt防止篡改的原理我会在后续讲到。

授权码模式         最安全的模式,也是需要步骤最多的模式,具体的步骤为:client在第三方(支付宝)提供的应用服务器上进行登陆验证后,验证服务器会返回给client一个授权码(code),此时这个code已经在验证服务器中完成了注册,我们访问其他资源的时候就需要携带这个code进行访问,此时就算code被盗取,那也毫无意义,因为想要获取token,是需要code+secret一起去生成token的,而这个secret是应用服务器和验证服务器内部之间已经约定好的一个密钥,外界是无法感知的。

1.3.通过RBAC模型动态分配资源

        RBAC(Resource Basic Access Control)资源访问控制是一种模型,此模型将用户和权限之间进行了分离,减少了耦合,接下来我以智慧出行网站为例,讲述如何实现了RBAC以及RBAC的好处。

        RBAC中包含用户(User)、角色(Role)、权限(Resource)这几种实体,一个用户可以对应一个角色或者多个角色,一个角色又对应多种权限。

        那么此时可能会有一些疑问,搞这么些实体干什么,有什么用? 我这里通过反向假设来进行验证。假如没有这三个实体,那么肯定至少有两个实体,其中一个是用户,一个是角色或者权限。

        如果是用户+角色来进行验证,假如此时智慧出行的后台管理只有拥有超级管理员这个role的用户才可以访问,那么有一天来了一个需求,需要新加一个角色,名为后台游客(就是可以访问后台,但不可以进行修改),那么我们就需要改动代码,在访问接口时,判断是否为超级管理员的时候还要判断是否是后台游客(如下图)。这肯定是不行的啊!那么多接口,你仅用一句话说加一个角色,我就要改一整天啊!所以这样的可维护性是极低的。

         如果是用户+权限来进行验证,这个就更不用说了,智慧出行网站目前有30多项权限,你要我都写到这个过滤器判断里一个一个判断?这显然不合理,况且我们在存储用户和权限的关系表时也是很费力的,光一个用户就对应那么多权限,维护的时候效率也极低而且容易出错。假如有这么一种情况,在智慧出行中,一般的用户是可以查询所有的城市的,假如说此时甲方说,不行,一般用户不可以获取我们全部的城市,那这个时候你是不是崩溃了?你不得一个一个去改用户的权限哈哈。所以这种也是不合理的。

        最后,如果是用户+角色+权限来进行验证,这就舒服多了,甲方你随便加角色,我只需要新建一个角色,然后给这个角色绑定上应有的权限,最后给这个用户分配角色就好了。而且维护的时候也很简单,修改权限只需要修改角色和权限的绑定关系即可。

1.4.jwt格式的token

        JWT(Json Web Token)是一种token的格式,它内部含有一些编码格式和加密算法。它分为三部分,分别是:头部(header)、负载(payload)、签名(signature)

        头部:存储声明类型(type=jwt)和加密算法(RS256、HS256等)。

        负载:存储用户的基本信息(这里不可以出现密码等敏感信息,否则会泄露密码),如用户名、邮箱、地址、角色、权限等。

        签名:签名的话是把上述的头部和负载进行Base64编码后再通过加密算法生成,其中secret存储在服务器,注意,这里就是jwt防止篡改的重点,因为client是不知道secret的,所以我们无法解密signature中的信息,当我们携带此token请求后端服务时,服务器通过secret把signature解密后获得的sinature中的header和payload与整个jwt中的header和payload进行比较,如果两者不一样,说明此token已被篡改,直接报错。

        下图为智慧出行网站的token,可以看出jwt格式的token还是很长的,payload的信息越多就越长。 jwt极大的提高了token的安全性,唯一的缺点就是太长,不过这也不算什么大事。

1.5.核心配置文件

        在SpringSecurity原有的过滤器链基础上加入Oauth2.0的一些额外的过滤器,所以有两个配置文件,一个是security基础的,一个是oauth2.0额外的。他们的配置规则几乎差不多,差别就是Oauth2.0需要额外配置客户端、端点和令牌的一些东西。

SecurityConfig.java

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true) //启用方法级别的权限认证注解PreAuthorization
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    //BCrypt加盐加密
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    //加入我们自己的userDetailsService
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
根据程序员青戈的博客中的引用,可以得知他在Vue项目中使用了axios库。在这个博客中还提供了一个常用的配置文件request.js,其中包含了axios的一些设置和拦截器的使用。在这个配置文件中,可以看到axios的一些常用配置,比如设置请求的baseURL、设置超时时间、设置请求头等。此外,还可以看到request.js中使用了axios的拦截器,可以在请求发出前和响应返回后对请求进行一些处理。对于具体的代码细节可以参考引用所提供的代码片段。 所以,根据程序员青戈的博客,他在Vue项目中使用了axios,并使用了一个名为request.js的配置文件来对axios进行一些设置和拦截器的使用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [关于axios封装的基本用法](https://blog.csdn.net/XZXLOVELXY/article/details/126338822)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [零基础搭建一个基于springboot加vue的前后端分离管理系统(一)详细学习笔记](https://blog.csdn.net/m0_52780355/article/details/121417250)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值