O2O全栈项目学习分享
项目介绍
这个项目是为****公司开发的一个o2o模式的项目,把所有餐馆资源整合打造冻品物流,提供食材配 送基本服务,还提供小吃、烧烤等外卖服务,是一个以冻品市场为核心的综合平台。它主要有组织机构、用户、服务、商品、订单、支付等模块,采用了前后端分离开发模式,前端有后台管理及主站,后台管理使用vue技术栈,主站使用html+css,后端使用springboot+ssm架构,部署使用docker。
负责模块
-
用户模块
用户注册、用户登录(账号登录、验证码登录、三方登录)、用户收藏(店铺、商品)、用户信息管理(基本信息、地址、支付信息) -
订单模块
订单(商品订单、采购订单、充值订单等)、系统报表、定时取消
使用技术
- FastDFS:图片上传,减轻服务器压力且支持集群
- Quartz:定时任务(订单超时取消、确认),相较于Timer可以持久性作业,并且可以对调度作业进行管理
- 百度地图:方便用户选择地址、解析用户地址为经纬度,计算最近店家
- MD5加密:加密加salt保存用户的密码
- 短信技术:用户注册、登录发送验证码
- 邮件技术:推送相关信息
- 微信三方登录:避免注册、登录繁琐的过程,用户体验更好
- Docker:部署项目
- Vue技术栈:elementUI、axios、webpack、vue cli
模块小结
-
用户模块
用户分为员工和用户,为了方便后台管理及主站使用一个登录接口,员工、用户表中添加一个type字段来区分,并增加一张loginInfo登录信息表,操作员工、用户时同步操作loginInfo
1.1用户注册:
1.2 用户登录:用户登录分为账号登录、验证码登录及三方登录
账户登录:通过前台传来的对象与数据库中的登录信息对比,验证通过就在redis中存入当前用户设置30分钟有效时间,并返回一个token,每次与后台交互后重置有效时间;
验证码登录:与用户注册相似;
三方登录:采用OAuth2.0授权码模式(authorization code)
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI",同时附上一个授权 码。
(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后 台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和 更新令牌(refresh token)。
以微信为例
1.前台主站发起授权请求,请求中设置回调地址;
2.跳转到扫码页面,用户扫码通过;
3.跳转到回调页面中,解析地址得到code,将code和绑定页面url传回后台;
4.后台通过HttpClients发起请求获取accessToken和openId;
5.通过openId在微信用户表中查询到用户;
6.如果用户存在就免密登录,用户不存在将重定向的url返回给前端跳转至绑定页面;
7.绑定页面类似登录,如果用户输入的账号已存在且密码正确,就直接完成绑定并免密登录,如果密码错误则提示;如果账户不存在则创建账户并完成绑定再进行登录
-
订单模块
主要订单种类:
1.用户充值订单;
2.外卖订单;
3.食材订购订单;
4.食材预定订单;
5.配送订单;
基本流程:
问题解决
- 跨域解决
跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。
- 开发阶段使用SpringMVC提供的CORS跨域过滤器:CorsFilter
优点:1.在服务端进行控制是否允许跨域,可自定义规则;2.支持各种请求方式
缺点:会产生额外的请求 - 部署时使用Nginx反向代理
- 登录状态保存
没做前后端分离之前,用户访问服务器在服务器端产生session并存储。现在每一次请求页面,80服务器还要向后台8080发起请求,如果前端没有以cookie的方式携带jssionid到服务器。后台服务是没有办法保持会话。
解决方案:登录成功,用uuid生成一个随机数,将该随机数作为key,用户信息作为value存入redis,作为一个token传到前端,前台将它放到localStorage中,并且我们在每次发起请求到后台时,都会在请求头中放入该token(通过axios前置拦截器,在所有请求发起前,判断token是否存在,如果存在就在请求的header中加入token),在后台的拦截器中,我们会获取每一个请求的token,如果没有token或者通过该token在redis中没有获取到相应的用户信息,都认为它没有登录,然后返回前台,否则就放行该请求。
缺点:1.浏览器会把localStorage的值类型限定为string类型,对于JSON对象需要转换;2.IE8以上的IE版本才支持localStorage;3.localStorage在浏览器的隐私模式下面是不可读取的
- 当前登录用户获取
通过WebApplicationContextUtils在不受spring管理的类中获取受spring管理的对象
public static LoginInfo getLoginInfo(HttpServletRequest request){
String token = request.getHeader("token");
// ApplicationContext spring容器 通过获取bean
WebApplicationContext context = WebApplicationContextUtils
.getWebApplicationContext(request.getServletContext());
//RedisTemplate有两个对象在spring中都注册了 所以不能通过class获取,要通过名称获取
RedisTemplate redisTemplate = (RedisTemplate) context.getBean("redisTemplate");
Object loginInfoObj = redisTemplate.opsForValue().get(token);
if (loginInfoObj!=null){
LoginInfo loginInfo = (LoginInfo) loginInfoObj;
return loginInfo;
}
return null;
}
本文地址:https://blog.csdn.net/m0_48261319/article/details/108749891
上一篇: word2007新建样式方法解读