华阳购物商城描述

一、背景介绍
华阳购物商城项目是一个全品类的电商购物网站,目前提供了基于H5的购物网站,基于小程序的客户端还在开发中,服务端基于springcloud技术栈搭建微服务群,对外提供统一的RESTful风格接口,实现对多端的统一支持,采用了前后端分离的架构方式,前端采用Vue技术栈,后端采用springcloud技术栈,从使用者角度划分为前台门户系统,后台管理系统。服务端采用springcloud技术形成微服务集群。
二、系统模块划分
项目主要分为商品微服务、搜索微服务、交易微服务、用户微服务模块。
三、在项目中责任描述
在这个系统中我主要负责的模块是用户的注册登录和购物车模块的开发,其中在开发用户的登录功能之前我考虑是采用无状态登陆还是有状态登录,为了提高身份认证效率和提升后台服务的延展性,我采用的是jwt的无状态登录,它可以把用户的信息封装成一个token返回给用户,用户登录时只需要携带这个token即可,这样我们的服务器不用保存用户数据,节省了资源,而且我们的服务也不用在每次在登录请求时都去请求一个服务去验证登录者身份,提升了服务的延展性。
采用JWT+非对称加密的方式实现用户的无状态登录。
那么什么是JWT呢?
JWT是Json风格的轻量级的授权和身份认证规范,可实现无状态、分布式的Web应用授权,jwt包括头部,头部主要是声名类型、和加密算法,我们采用的是rsa非对称加密,还有载荷,里面是用户的身份信息,因为载荷里面采用的是base64加密的,这是一种可解密的加密方式,所以这里面不能放用户的敏感信息,所以我将能够识别用户身份的id和用户名放在载荷中,第三部分是数字签名,这部分是前两部分数据通过rsa非对称加密生成的。
四、注册功能介绍
用户通过操作前台页面向后台发送请求携带自己的信息,我们拿着手机号和用户名先判断此用户是否存在,如果两个中有一个已经存在,就返回给用户说已经存在,如果不存在,就从redis中拿出之前保存的验证码,和传过来的验证码进行匹配,匹配正确之后,调用Spring提供的BcriptPasswordEncoding加密算法来生成salt盐,为了确保盐的安全性,我们使用uuid生成一个随机的密钥配置到Bcirpt,拿到盐之后就对密码进行加密存入到数据库中,到这一步说明用户注册成功,如果想要验证密码需要拿到用户加密前的密码,推断出salt,再拿着salt对未加密的密码进行加密,最后和自己已经加密的密码进行比较。
五、登录功能介绍(涉及到设置超时和更新超时时间)
用户点击登录后就发送请求到鉴权中心,鉴权中心微服务通过feign调用用户微服务向外暴露的restful接口,通过用户输入的用户名和密码去数据库查询用户名和密码是否正确。因为我们在做用户注册的时候为了保证用户密码的安全性,所以我们将用户密码进行了加盐然后通过BcriptPasswordEnconding加密之后再存入到数据库的,数据库中也有salt这个字段,所以我们在调用用户微服务的时候,是通过用户名进行查询用户的,然后取出盐,将用户输入的密码进行BcriptPasswordEnconding加密操作和数据库中的salt(加密后的密码)进行比较,如果密码一致,说明是同一个用户,然后根据用户信息生成一个jwt存放在cookie中返回给用户,用户登陆成功。
登录成功之后当用户访问其他的微服务时需要进行鉴权操作,判断其是否登录成功,许多微服务都会涉及到用户登录状态验证,所以我们需要配置一个拦截器以及相关的拦截路径和放行路径,用户发送请求时直接获取用户cookie中jwt,若jwt为空,则未登录,若jwt非空则验证jwt,获取用户信息,其他服务申请密钥,给每个微服务都设置一个身份信息,服务想要获取密钥,就携带着自己的身份信息去请求存放密钥的服务,存放密钥的服务拿到请求服务的信息后就去数据库中进行对比,如果正确就把密钥返回给其他服务。
我们在做完以上的功能之后,发现我们并没有对用户的jwt设置超时,这对jwt的安全性是有一定的影响的,所以我们考虑需要给jwt设置超时,有两种设置方法,一种是直接在生成jwt时设置,一种是在之后通过jwt唯一标识jti带上超时时间存放于redis中,因为jwt的签名一旦生成就不能修改,所以我们采用了第二种,这时候就需要对之后的登录和验证登录模块进行完善,我们首先在登录功能中把用户id作为key,jti作为value存放到redis中,并设置过期时间,之后再把jwt返回给用户。在鉴权的时候就需要取出用户jwt中携带的jti,并且拿着用户id取出redis中存储的jti,如果jti没有的话,就证明用户已经登陆超时,如果存在就两个进行比较。
当我们的用户在浏览页面或者付款的时候因为超时时间结束而爆出了登录超时或未登录,那样对我们用户的体验感是极差的,所以我们需要做到,当用户一直访问,redis的jti就不会失效消失,需要不断的更新超时时间,如果在超时时间内一直没有访问,就让jti消失,综上我们只需要让我们的用户在访问服务时,直接拦截用户,根据用户id刷新存在于redis的超时时间即可,又因为我们的用户不管访问那个服务都需要经过我们的网关,所以我们在网关需要配置一个过滤器去拦截所有的请求,如果是已经登陆的用户就利用redis的expire命令去刷新用户超时时间然后放行,如果没有登录则直接放行交给之后的业务逻辑去处理。这样就可以保证我们的用户一直浏览页面不会出现超时的情况。
六、购物车模块
用户在浏览商品的时候可以将自己中意的商品加入购物车当中,用户可以查看、删除购物车中的商品,或者修改购物车中商品的数量,在购物车中选中自己的加购的商品进行下单业务。
用户在登录或未登录的状态下都可以添加购物车,所以当用户添加购物车的时候我们判断用户是否登录,鉴权中心已经提供了判断用户是否登陆的接口,直接在用户点击加入购物车时判断用户是否登录即可。
分两种状态访问购物车模块(用户未登录、用户已登录)
未登录时:
当用户未登录时商品是存放在浏览器的localStoarge,以json(其实也是String的格式)存储,此外localStoarge存储是永久有效的,不会因为用户关闭窗口让本来就加入购物车的商品消失,不选择存放在cookie是因为cookie的存储大小有限制,购物车页面的数据量大,不适合存放在cookie页面。
已登录时:
而登录的状态下我们将加入购物车中商品以hash的形式存放在redis中,map的外层key是用户的id,内层key是商品的id,value则是我们定义的一个购物车中商品类cart,cart类中除了商品信息,我们还增加了所属用户的id,我们将购物车的数据存放在redis中而没有存放在数据库是因为除了购物车中的商品涉及到大量的增加删除,修改商品数量的操作,主要还因为购物车中会显示当前商品的价格和之前加入购物车中商品的价格之间的差价,所以放在reids中就会保存用户添加入购物车中商品的那个价格。
当用户没有登录的时候操作购物车是直接在web的本地存储中进行购物车商品的增加删除操作。
当用户已经登录要进行购物车操作是就需要通过购物车微服务了,购物车微服务提供接口只有在登录状态下才能操作,所以我们给购物车为服务添加了一个springMVC过滤器,判断用户是否登录,因为用户的信息在购物车所有的接口中都是要使用的,所以为了避免代码冗余,我们在过滤器中获取哟过户的信息,存放在threadLocal中,并提供了获取信息的静态方法,这样就可以直接获取到用户信息了。获取到用户信息后,可以根据用户的id对购物车进行增加修改删除的操作。
当用户选择下单后会校验用户是否登录,如果没有登录则跳转待到登录页面让用户进行登录,登录成功后跳转到购物车界面,在这里进行购物车合并功能,将存放在localStoarge的购物车商品和redis中添加购物车的商品根据用户id进行合并,合并之后将localstoarge的数据删除。这样可以防止重复合并。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

also&lucky

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值