开发系统

未完善,仅供参考!!!

一、网站登录变迁过程概述

(一)认证方式一

早期互联网网站采用的是Cookie-Session方式,也是当时最常用的方式,直到现在仍有不少网站在沿用这种认证方式。
1、认证过程大致如下
(1)用户输入用户名、密码或者用短信验证码方式登录系统;
(2)服务端验证后,创建一个 Session 信息,并且将 SessionID 存到 cookie,发送回浏览器;
(3)下次客户端再发起请求,自动带上 cookie 信息,服务端通过 cookie 获取 Session 信息进行校验
2、弊端
(1)只能在web场景中使用。
(2)需要考虑跨域问题,cookie不能跨域。
(3)存在跨站请求伪造的风险。
(4)分布式系统中,需要考试session同步问题。
(5)小程序公众号存在现在。

(二)认证方式二

1、Cookie-Session方式的改进版
(1)可以看到上面有很多弊端问题,后来便有了token的方式来做验证。改动的地方如下:
(2)用户通过用户名、密码登录,登录成功后返回一个token字符串,服务器保存token信息用于验证。
(3)客户端拿到token后,以后每次请求都带上token信息。
(4)token可以保存在非关系型数据库中。避免了session同步问题。
2、弊端
服务端需要存储token,用户量庞大会增加服务器压力。

(三)认证方式三

基于jwt+token的认证方式,JWT(JSON Web Token)是一个非常轻巧的规范。

1、认证过程
(1)依然是用户登录系统;
(2)服务端验证,将认证信息通过指定的算法(例如HS256)进行加密,例如对用户名和用户所属角色进行加密,加密私钥是保存在服务器端的,将加密后的结果发送给客户端,加密的字符串格式为三个"." 分隔的字符串 Token,分别对应头部、载荷与签名,头部和载荷都可以通过 base64 解码出来,签名部分不可以;
(3)客户端拿到返回的 Token,存储到 local storage 或本地数据库;
(4)下次客户端再次发起请求,将 Token 附加到 header 中;
(5)服务端获取 header 中的 Token ,通过相同的算法对 Token 中的用户名和所属角色进行相同的加密验证,如果验证结果相同,则说明这个请求是正常的,没有被篡改。这个过程可以完全不涉及到查询 Redis 或其他存储;
2、优点
(1)使用 json 作为数据传输,有广泛的通用型,并且体积小,便于传输;
(2)不需要在服务器端保存相关信息;
(3)jwt 载荷部分可以存储业务相关的信息(非敏感的),例如用户信息、角色等;

(四)认证方式四

OAuth2.0是什么呢,Oath的核心是向第三方颁发令牌。发放令牌有四种授权方式:

1、授权码

第三方应用先申请一个授权码,然后再用该码获取令牌。这种方式是最常用的流程,安全性也高,它适用于那些有后端的web应用。授权码通过前端传送,令牌则是存储在后端,采用前后端分离的方式,防止令牌泄漏。
(1)第一步,A网站提供一个链接,用户点击后就会跳转到B网站,授权用户数据给A网站使用。
https://b.com/oauth/authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read
上面URL中,response_type参数表示要求返回授权码,client_id参数是让B知道是谁在请求,redirect_uri参数是B接受或拒绝请求后跳转的网址,scope参数表示要求的授权范围,read只读。
(2)第二步,用户跳转后,B网站会要求用户登录,然后询问是否同意给予A网站授权。用户表示同意,这时B网站就会跳转到redirect_uri参数指定的网站。跳转时会传回一个授权码。
(3)第三步,A网站拿到授权码后,就可以在后端申请令牌,拿到令牌后,接口会返回一串json数据,包括令牌,有效时长等信息。

2、隐藏式

这种方式常用于没有后端的网站。秘钥必须保存在前端,少了请求授权码,直接获取token

3、密码式

这种用于第三方极其信用的系统,一般用户内部多系统之间首先,需要使用用户名密码。

4、客户端凭证

适用于没有前端的命令行应用,即在命令行下请求令牌。
这四种授权方式的共同点是,第三方应用申请令牌之前,都必须先到系统备案,拿到客户端id和客户端秘钥,没有备案的第三方系统是拿不到令牌的。
了解完登录模块后,我们需要分析架构图,设计数据库,选择开发语言,编码,测试等。首先菜单,角色,用户等是每个系统中都必须的,用于管理系统,控制资源。

二、根据三范式设计MySQL关系表

(一)数据库相关设计

1、第一范式1NF:确保每个字段保持原子性,不可分割。
对于用户表users来说,有用户姓名(一般由first_name和last_name组成),如果使用类似Oracle的复合数据类型,就违反了1NF。很明显users的字段user_name是一个自定类型,是可分解的,这就违反了1NF。

2、第二范式2NF:确保字段完全依赖于主键。

一个表中只能保存一种数据,不可以把多种数据保存在一张表里,假如一张表既存储了用户信息,又存储商品信息,还存储了订单信息,这样就违反了2NF,而应该将用户表,商品表,订单表拆分成三张表,确保字段是该表拥有的。

3、第三范式3NF:必须满足2NF,实体中每个属性与主键直接相关而不能间接相关。

这个也不难理解,对于订单表orders来讲,是要存储用户表users的user_id,要明确哪个用户下的单,有些业务场景是要获取users表的用户姓名user_name,为了减少orders和users表的关联查询,将user_name冗余到orders表中,这种设计就违反了3NF,减少数据冗余,可以通过主外键进行表之间连接。
(二)数据表结构如下

1、用户表(sys_user)

系统用户基本信息,保存用户名,密码,身份证号,姓名等个人基本信息。
字段名 类型 长度 是否为空 注 释
id int 10 否 主键,自增
real_name varchar 20 否 用户名称
user_name varchar 20 否 用户编码
password varchar 20 否 用户密码
phone varchar 20 是 联系方式
create_time datetime 0 是 创建时间
update_time datetime 0 是 修改时间
status int 4 否 0正常,1禁用

2、角色表(sys_role)

管理系统资源权限
字段名 类型 长度 是否为空 注 释
id int 10 否 主键,自增
role_code varchar 20 否 用户编码
role_name varchar 20 否 角色名称
description varchar 20 是 描 述
create_time datetime 0 是 创建时间
update_time datetime 0 是 修改时间
status int 4 否 0正常,1禁用

3、菜单表(sys_menu)

对应前端页面中的每个菜单及按钮
字段名 类型 长度 是否为空 注 释
id int 10 否 主键,自增
menu_name varchar 20 否 菜单名称
menu_url varchar 20 否 菜单地址
path varchar 20 是 前端路径
parent_id int 10 是 父级id
create_time datetime 0 是 创建时间
update_time datetime 0 是 修改时间
status int 4 否 0正常,1禁用

4、用户角色表(sys_user_role)

一个用户可能对应多个角色,所以提取出了用户和角色关系表
字段名 类型 长度 是否为空 注 释
id int 10 否 主键,自增
user_id int 10 否 用户id
role_id int 10 否 角色id
create_time datetime 0 是 创建时间

5、菜单角色表(sys_menu_role)

角色拥有多个菜单权限,提取出菜单角色表
字段名 类型 长度 是否为空 注 释
id int 10 否 主键,自增
user_id int 10 否 用户id
role_id int 10 否 角色id
create_time datetime 0 是 创建时间

我们选择第二种认证方式:原因是逻辑清晰相对简单,虽然token是需要保存在服务端,但不是每个系统都有庞大的用户量,所以不用考虑服务器压力太大,再者这种方式不会像session处处受到限制。
我们认证的方式是用户名密码,首先需要在数据库中新增一条用户信息。当然,用户的密码是加密的,只有用户自己知道,我们是无法获取到用户的隐私信息,所以大家不要担心登录别的系统,人家都有保存你的密码,信息轻易会被盗取。

那系统是如何做到接口权限的呢?比如安全电子政务网站,目前有系统管理菜单,系统管理下有用户管理菜单。用户管理有增加,修改,删除以及用户列表。但不是每个人都有权限修改用户的信息,或者新增,删除用户。系统是根据角色来管理资源权限的。假如系统目前有两个角色,超级管理员和普通角色。超级管理员具有用户菜单中新增,修改,删除,以及查看功能,因为是超级管理员,则有最高权限。而普通角色只能查看系统有哪些用户,只有查询权限,而不能做修改等操作。

那每次请求都要去数据库查询角色菜单信息验证用户是否有权限访问当前资源吗?傻瓜,当然不是,用户量,并发量增大,这样数据库的压力会倍增。那怎么办?你使用用户名密码登录成功后,系统会把你的个人信息、角色、菜单、以及可以访问哪些资源等都会封装起来,保存到redis的数据库。那redis数据库就没有瓶颈吗,为什么mysql压力太大扛不住,redis就可以。因为mysql是关系型数据库,用户维护复杂的数据关系,数据是保存在磁盘里的,每次都要进行磁盘io,花费的时间较长。而redis数据是保存在内存中的,读写数据超快,理论可以达到10万/1s。

比如拥有普通角色的用户,登录系统后想修改某个用户的个人信息。通过其它方式登录账户后,访问修改接口(因为我们自己网站根据接口信息知道该用户没有修改权限,则他是无法看到修改菜单的)。系统首先会查看该用户拥有的资源权限,发现权限不足则返回提示信息。

三、电子政务网站存在的问题?

首先系统通过角色菜单等已经限制了哪些用户可以登录系统,但不妨出现一些意外。管理员勿操作删了某个用户信息,管理员密码被盗等特殊情况。1. 系统中较为重要的数据是不会物理删除的,大多都是逻辑删除,哪怕被误删了也能恢复。类似于我们电脑上,手机相册等回收站。

(一)回收站

删除内容后一段时间数据是在回收站,可以在回收站恢复数据,但往往这些回收站信息是为个人服务的,如果从回收站中删除了,数据是真的删除了,再想找回可谓 难上加难。

(二)资源权限以及限流

而我们网站往往是不会提供回收站功能的,你做了删除操作,那么用户是以为真的删除了,只有后台保存了状态。如果想要恢复数据,需要寻找网站维护者帮助恢复数据。2. 系统每个敏感操作都是有记录的,例如登录,新增,修改,删除等操作,并且记录的信息有ip地址,设备相关信息,时间,登录用户等,如果发生数据丢失,也能及时通过查询日志找到相关人员。


因为每个人都对应一个或多个角色,每个角色都有不能的资源分配权限,只有超级管理员拥有所有资源访问权限,有权限的划分,不光是通过角色配置后页面看不到增删改相关操作,且在接口层面也做了相关拦截。进一步确保了数据的安全性。


一般政府单位可能会接入指纹、指静脉的登录,那系统如何实现通过指纹、指静脉登录呢?
当然,接入硬件总不能去完成硬件相关编码吧,那接入的成本太高了。指纹、指静脉厂家已经帮我们实现了核心的算法,我们只需要调用第三方本地库,生成字节后保存起来。验证的时候同样的方式,也是调用算法库,生成字节文件。和库中的文件进行算法对比,对比分数较高则可登陆成功。指纹和指静脉的思路是一致的。

(三)如何保证系统的安全性

可能会有人问,如果存在恶意暴力破解密码该怎么办,利用机器重复破解数次,直到匹配成功。不知道大家有没有银行卡被锁的经历,输入三次错误密码账号将被锁定,需要联系相关人员进行解锁或者指定的天数后自动解锁。通过这种方式保障了系统被恶意破解,且我们在也做了IP限流。
网站还想接入微信、微博等常用软件登录,则可以实现OAuth2.0来接入通过微信等第三方登录网站,但相应的权限也是最基础的。

(四)接口文档是以哪种方式展示的

开发完基础模块,就需要开发相应的业务。因现在都采用前后端分离的模式,需要给前端提供接口文档。使用Swagger2.0框架,只需要少量的注解就能生成接口文档供前端开发调用。当然,很多公司都是自己开发的接口平台,毕竟使用开源的项目多少是有风险的。考虑我们要开发的是电子政务系统,则接口文档采用文档的形式加密提供。
与前端联调可能花费的时间较多,如果有完整的原型图,开发周期便能缩短很多。调试过程中可能会遇到很多问题,但对于有经验的开发者来说,踩过的坑会尽可能的避开。

(五)如何保证系统可以用,减少bug

功能开发完成后,接口以及界面需要开发人员测试通过,编写测试单元,至少自测通过。但开发人员自测通过后不代表就能上线。只是站在开发者的角度解决问题,觉得系统已接近完美。但往往并不是这样,系统还存在很多潜在的因素,一般公司会配备专业的测试。测试合理性,可用性,并发量等。
通过测试这一关,电子政务系统算是完成了一大半。什么,竟然还没完。是的,一个系统的开发过程并没有那么简单,繁杂的过程都是为了保证系统的稳定性,用户良好的体验。


相比Windows,Linux系统更适合做服务器,稳定且实用。是的,我们接下来需要把系统部署到真实环境中,这需要一定的Linux基础,包括在Linux上安装相关软件,防火墙以及安全组等相关配置。最后部署我们的服务开发端口,第一阶段算是完成了部署。


但电子政务系统是对外开放的。流量不可控,可能会有很多访问量导致系统奔溃,无法返回正确的响应,我们总能遇到比如车票系统奔溃,教育系统奔溃。因为用户量太庞大,系统很难支撑亿级流量。当然我们系统可能并不会有那么多的并发量,但是相应处理还是应该有的。首先需要搭建集群,增加系统的并发量。其次做服务降级等操作,确保主服务高可用行。最后还需要服务熔断,考虑超过过多并发量系统支撑不了,停止服务。

四、结论

因为篇幅因为简化了很多操作。比如开发系统前需要概要设计、用例、设计图、效果图、流程图等。数据库同样也需要根据设计图以及架构图设计,需要概要设计等。一个软件的开发生命周期是较长的,很多已经形成了流程,前提条件准备好了,开发时也会较少很多不必要的问题。甚至能够有效的缩短开发周期,降低开发成本。很多时候往往是因为需要变动太大,代码被改的面目全非,甚至无从下手。所以开发前的前置工作是必不可少的。开发也不能过于着急。安全问题很重要,万一数据库泄漏,轻则被删库敲诈,重则丢失重要的数据。可能造成的损失是不可估量的,做为开发人员,总不能面向监狱编程吧。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

失忆老幺

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

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

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

打赏作者

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

抵扣说明:

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

余额充值