用户中心

用户中心

介绍

对其他项目的用户模块进行统一的管理

需求分析

  1. 登录/注册
  2. 用户管理(仅管理员可见)对用户的查询或者修改
  3. 用户检验(仅客户)

暂时不实现

  1. 权限管理(企业中使用,在很细的权限需求中使用)
    解释:一般情况下没必要找那么复杂,需要根据实际情况设计

技术选型

前端:

三件套 + React 组件库 Ant Design

  • Umi(阿里巴巴开发框架) + Ant Design Pro(现成的管理系统)

后端:

  • java
  • spring(依赖注入框架,帮助你管理 Java 对象,集成一些其他的内容)
  • springmvc(web 框架,提供接口访问、restful接口等能力)
  • mybatis(Java 操作数据库的框架,持久层框架,对 jdbc 的封装)
  • mybatis-plus(对 mybatis 的增强,不用写 sql 也能实现增删改查)
  • springboot(快速启动 / 快速集成项目。不用自己管理 spring 配置,不用自己整合各种框架)
  • junit 单元测试库
  • mysql

部署:

服务器/容器(平台)

计划

  1. 初始化项目
    1. 前端初始化
      1. 初始化项目
      2. 引入一些组件
      3. 框架介绍/瘦身
    2. 后端初始化
      1. 准备环境(比如MySQL)
      2. 引入框架(整合框架)
  2. 登录/注册
    1. 前端
    2. 后端
      1. 规整项目目录
      2. 实现基本数据库操作(操作user表)
        1. 模型user对象=>和数据库的字段关联,自动生成
      3. 写登录逻辑
  3. 用户管理(仅管理员可见)
    1. 前端
    2. 后端

前端笔记

环境安装

Node链接
https://nodejs.org/en
yarn安装命令
npm install --global yarn
安装umi-ui(项目目录下)
tyarn add @umijs/preset-ui -D
npm install --save-dev @umijs/preset-ui

Ant Design Pro使用

下载

推荐拉取github的地址
https://github.com/ant-design/ant-design-pro.git

安装依赖

cmd进入项目目录输入yarn安装

启动

执行根目录的package.json中的start(其中没有后台,数据是MOCK模拟出来的)
如果执行start:dev就会关闭数据模拟

如果无法启动

一般是node版本问题,使用nvm管理工具
还有index.md文件报错,把index.md删了就可以跑了

检测不同地区的原理

file

ts是对js的强化

不能直接把js转为ts

后端笔记

初始化项目

三种初始化 Java 项目的方式

  1. GitHub 搜现成的代码
  2. SpringBoot 官方的模板生成器(https://start.spring.io/
  3. 直接在 IDEA 开发工具中生成 ✔

如果要引入 java 的包,可以去 maven 中心仓库寻找(http://mvnrepository.com/

Spring Boot测试类问题(未解决)

不指定测试类的入口,默认是自己的类名(减去Tests)

ResourceAutowired的区别

Resource他会默认先按照,Java并的名称去注入
然后如果是Autowired的话,他只会按照类型去注入
(如果找不到匹配的bean或者存在歧义(多个匹配的bean),则会报错)
所以一般用Resource来自动注入

数据库设计

用户表:
id (主键) bigint
userName 名称 varchar
userAccount 登录账号 varchar
avatarUrl 头像 varchar
gender 性别 tinyint
passWord 密码 varchar
phone 电话 varchar
email 邮箱 varchar
userStatus 状态(比如被封号之类的) tinyint 0 1


createTime 创建时间 (数据插入时间) datetime
updateTime 更新时间 (数据更新时间) datetime
isDelete 是否删除 0 1 (逻辑删除) tinyint
[不是真的删除,而是通过0和1表示这条数据是否有效]

这三个字段的作用是和业务没有任何关系的
就无论你是什么表,理论上都需要有这三个字段

设计笔记

有人说后面补充的话不麻烦吗

因为如果你根本都没有想到,后面可能会有什么需求的话
你现在补充过来,结果这些字单根本不用,这反而就是过度设计了呀

不是不能驼峰吗,为什么不是下划线

从来没有人说过数据库设计不能驼峰,不要纠结这些东西

自动生成器的使用

MyBatisX 插件,自动根据数据库生成 domain 实体对象、mapper(操作数据库的对象)、mapper.xml(定义了 mapper对象和数据库的关联,可以在里面自己写 SQL)、service(包含常用的增删改查)、serviceImpl(具体实现 service)

注册逻辑

  1. 用户在前端输入账户和密码、以及校验码(todo)
  2. 检验用户的账户、密码、检验密码,是否符合要求
    1. 非空
    2. 账户的话不小于4位
    3. 密码就不小于8位
    4. 账户不能重复
    5. 账户不包括特殊字符
    6. 密码和检验密码相同
  3. 对密码进行加密(密码千万不要直接以明文存储到数据库中)[加盐的目的其实主要就是去把这个算法的要加密的内容,给他更混淆一下]
  4. 向数据库插入用户数据

登录接口

接受参数:用户账户、密码

请求类型:POST

请求体:JSON 格式的数据

请求参数很长时不建议用 get

返回值:用户信息( 脱敏

登录逻辑

  1. 校验用户账户和密码是否合法
    1. 非空
    2. 账户长度 不小于 4 位
    3. 密码就 不小于 8 位吧
    4. 账户不包含特殊字符
  2. 校验密码是否输入正确,要和数据库中的密文密码去对比
  3. 用户信息脱敏,隐藏敏感信息,防止数据库中的字段泄露
  4. 我们要记录用户的登录态(session),将其存到服务器上(用后端 SpringBoot 框架封装的服务器 tomcat 去记录)
    cookie
  5. 返回脱敏后的用户信息

控制层 Controller 封装请求

application.yml 指定接口全局 api

servlet:
  context-path: /api
@RestController 适用于编写 restful 风格的 api,返回值默认为 json 类型

controller 层倾向于对请求参数本身的校验,不涉及业务逻辑本身(越少越好)
最好在controller完成对所有请求参数的检验(尽量全面),获取尽量是以请求体的形式(为了反正报错)
file

service 层是对业务逻辑的校验(有可能被 controller 之外的类调用)

如何知道是哪个用户登录了?

(javaweb 这一块)

  1. 连接服务器端后,得到一个 session 状态(匿名会话),返回给前端

  2. 登录成功后,得到了登录成功的 session,并且给该sessio n设置一些值(比如用户信息),返回给前端一个设置 cookie 的 ”命令“

    session => cookie

  3. 前端接收到后端的命令后,设置 cookie,保存到浏览器内

  4. 前端再次请求后端的时候(相同的域名),在请求头中带上cookie去请求

  5. 后端拿到前端传来的 cookie,找到对应的 session

  6. 后端从 session 中可以取出基于该 session 存储的变量(用户的登录信息、登录名)

  7. 给用户脱敏

用户管理接口

!!! 必须鉴权

  1. 查询用户
    1. 允许根据用户名查询
  2. 删除用户

写代码流程

先做设计

代码实现

持续优化!!!(复用代码、提取公共逻辑 / 常量)

前后端交互

前端需要向后端发送请求

前端 ajax 来请求后端

axios 封装了 ajax

request 是 ant design 项目又封装了一次

追踪 request 源码:用到了 umi 的插件、requestConfig 是一个配置

代理

正向代理:替客户端向服务器发送请求,可以解决跨域问题

反向代理:替服务器统一接收请求。

怎么搞代理?

Nginx 服务器

Node.js 服务器

原本请求:http://localhost:8000/api/user/login

代理到请求:http://localhost:8080/api/user/login

登录态

有些人问我cession和totem维持登录,建议用哪个,这都根据你自己的实际情况,如果说你不需要单点登录的话,你一般用的cession就足够了。
毕竟cession的无论是开发成本还是理解成本,相对都简单一点。
对大多数系统来说cession就足够了。

后端优化

  1. 通用返回对象
    目的:给对象补充一下信息,告诉前端这个请求在业务层面上是成功还是失败
    200、404、500、502、503
    (为什么我们要定义自己的错误码,是不是因为http状态码它默认的值比较少,不够精准)

    {
        "name": "yupi"
    }
    
    // 成功
    {
        "code": 0 // 业务状态码
        "data": {
            "name": "yupi"
        }
        "message": "ok"
    }
    
    // 错误
    {
        "code": 50001 // 业务状态码
        "data": null
        "message": "用户操作异常、xxx"
    }
    • 自定义错误码
    • 返回类支持返回正确和错误
  2. 封装全局异常处理
    1. 定义业务异常类
      1. 相对于java的异常类,支持更多字段
      2. 自定义构造函数,更灵活/快捷的设置字段
    2. 编写全局异常处理器
      1. 作用
        1. 捕获代码中所有的异常,内部消化,让前端得到更详细的业务报错/信息,
        2. 同时屏蔽掉项目框架本身的异常(不暴露服务器内部状态)
        3. 集中处理,比如记录日志
      2. 实现
        1. Spring AOP:在调用方法前后进行额外的处理
  3. 全局请求日志和登录检验