• 【笔记3-用户模块】从0开始 独立完成企业级Java电商网站开发(服务端)


    数据表结构设计

    file

    关系设计
    file

    为什么不用外键?
    分库分表有外键会非常麻烦,清洗数据也很麻烦。数据库内置触发器也不适合采用。

    查业务问题的后悔药——时间戳
    create_time 数据创建时间
    update_time 数据更新时间
    可以用于查询业务,主要要存储datetime类型。

    用户模块

    用户表
    file

    create table mmall_user(
    id int(11) PRIMARY key not null auto_increment comment '用户表id',
    username varchar(50) not null comment '用户名',
    password varchar(50) not null,
    email varchar(50) DEFAULT null,
    phone varchar(50) DEFAULT null,
    question VARCHAR(100) DEFAULT null,
    answer varchar(100) DEFAULT null,
    role int(4) not null,
    create_time datetime not null,
    unique key user_name_unique (username) using btree
    )engine=INNODB auto_increment=21 DEFAULT charset=utf8
    

    用户名username设置为唯一索引unique
    由于用户名是不能重复的,在并发的时候可以通过锁的形式解决,但是当架构变成分布式后,通过数据库底层的unique key唯一索引,交给mysql完成了唯一的验证。

    涉及知识点

    • 横向越权、纵向越权安全漏洞

    横向越权:攻击者尝试访问与他拥有相同权限的用户的资源
    纵向越权:低级别攻击者尝试访问高级别用户的资源

    • 高复用服务响应对象的设计思想及抽象封装

    file

    • MD5明文加密及增加salt值

    关于MD5网上又很多资料,是一个安全得散列算法,虽然过程不可逆,但是还是可以通过穷举法获取原值
    增加salt值(加盐值)可以一定程度上解决上面得问题,具体得看链接

    • Guava缓存的使用
    package com.mmall.common;
    import com.google.common.cache.CacheBuilder;
    import com.google.common.cache.CacheLoader;
    import com.google.common.cache.LoadingCache;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import java.util.concurrent.TimeUnit;
    
    public class TokenCache {
    
        public static final String TOKEN_PREFIX = "token_";
    
        private static Logger logger = LoggerFactory.getLogger(TokenCache.class);
    
        private static LoadingCache<String, String> localCache = CacheBuilder.newBuilder()
                .initialCapacity(1000)
                .maximumSize(10000) //本地最大缓存10000
                .expireAfterAccess(12, TimeUnit.HOURS) //缓存有效期
                .build(new CacheLoader<String, String>() {
                    //默认的数据加载实现,当调用get取值的时候,如果key没有对应的值,就调用这个方法进行加载
                    @Override
                    public String load(String s) throws Exception {
                        return "null";
                    }
                });
    
        public static void setKey(String key, String value) {
            localCache.put(key, value);
        }
    
        public static String getKey(String key) {
            String value = null;
            try {
                value = localCache.get(key);
                if ("null".equals(key)) {
                    return null;
                }
                return value;
            } catch (Exception e) {
                logger.error("localCache get error", e);
            }
            return null;
        }
    }
    
    
    • Session的使用

    Servlet的内置对象,具体查看Servlet九大内置对象

    • 方法局部演进

    功能模块

    file

    接口设计

    门户_用户接口

    1.登录

    /user/login.do post(代码需要post方式请求),开放get,方便调试

    request

    username,password
    

    response

    success

    {
        "status": 0,
        "data": {
            "id": 12,
            "username": "aaa",
            "email": "aaa@163.com",
            "phone": null,
            "role": 0,
            "createTime": 1479048325000,
            "updateTime": 1479048325000
        }
    }
    

    2.注册

    /user/register.do

    request

    username,password,email,phone,question,answer
    

    response

    success

    {
        "status": 0,
        "msg": "校验成功"
    }
    

    3.检查用户名是否有效

    /user/check_valid.do

    /check_valid.do?str=admin&type=username就是检查用户名。

    request

    str,type
    str可以是用户名也可以是email。对应的type是username和email
    
    

    response

    success

    {
        "status": 0,
        "msg": "校验成功"
    }
    
    

    4.获取登录用户信息

    /user/get_user_info.do

    request

    无参数
    

    response

    success

    {
        "status": 0,
        "data": {
            "id": 12,
            "username": "aaa",
            "email": "aaa@163.com",
            "phone": null,
            "role": 0,
            "createTime": 1479048325000,
            "updateTime": 1479048325000
        }
    }
    

    5.忘记密码

    /user/forget_get_question.do

    localhost:8080/user/forget_get_question.do?username=geely

    request

    username
    

    response

    success

    {
        "status": 0,
        "data": "这里是问题"
    }
    

    6.提交问题答案

    /user/forget_check_answer.do

    localhost:8080/user/forget_check_answer.do?username=aaa&question=aa&answer=sss

    request

    username,question,answer
    

    response

    正确的返回值里面有一个token,修改密码的时候需要用这个。传递给下一个接口

    success

    {
        "status": 0,
        "data": "531ef4b4-9663-4e6d-9a20-fb56367446a5"
    }
    

    7.忘记密码的重设密码

    /user/forget_reset_password.do

    localhost:8080/user/forget_reset_password.do?username=aaa&passwordNew=xxx&forgetToken=531ef4b4-9663-4e6d-9a20-fb56367446a5

    request

    username,passwordNew,forgetToken
    

    response

    success

    {
        "status": 0,
        "msg": "修改密码成功"
    }
    

    8.登录中状态重置密码

    /user/reset_password.do

    request

    passwordOld,passwordNew
    
    

    response

    success

    {
        "status": 0,
        "msg": "修改密码成功"
    }
    

    9.登录状态更新个人信息

    /user/update_information.do

    request

    email,phone,question,answer
    

    response

    success

    {
        "status": 0,
        "msg": "更新个人信息成功"
    }
    

    10.获取当前登录用户的详细信息,并强制登录

    /user/get_information.do

    request

    无参数
    

    response

    success

    {
        "status": 0,
        "data": {
            "id": 1,
            "username": "admin",
            "password": "",
            "email": "admin@163.com",
            "phone": "13800138000",
            "question": "question",
            "answer": "answer",
            "role": 1,
            "createTime": 1478422605000,
            "updateTime": 1491305256000
        }
    }
    

    fail

    {
        "status": 10,
        "msg": "用户未登录,无法获取当前用户信息,status=10,强制登录"
    }
    
    

    11.退出登录

    /user/logout.do

    request

    response

    success

    {
        "status": 0,
        "msg": "退出成功"
    }
    

    后台_用户接口

    1.后台管理员登录

    /manage/user/login.do

    request

    String username,
    String password
    

    response

    success

    {
        "status": 0,
        "data": {
            "id": 12,
            "username": "aaa",
            "email": "aaa@163.com",
            "phone": null,
            "role": 0,
            "createTime": 1479048325000,
            "updateTime": 1479048325000
        }
    }
    

    2.用户列表

    /manage/user/list.do

    request

    pageSize(default=10)
    pageNum(default=1)
    

    response

    success

    {
        "status": 0,
        "data": {
            "pageNum": 1,
            "pageSize": 3,
            "size": 3,
            "orderBy": null,
            "startRow": 1,
            "endRow": 3,
            "total": 16,
            "pages": 6,
            "list": [
                {
                    "id":17,
                    "username":"rosen",
                    "password":"",
                    "email":"rosen1@happymmall.com",
                    "phone":"15011111111",
                    "question":"啊哈哈",
                    "answer":"服不服",
                    "role":0,
                    "createTime":1489719093000,
                    "updateTime":1513682138000
                },
                {
                    "id":17,
                    "username":"rosen",
                    "password":"",
                    "email":"rosen1@happymmall.com",
                    "phone":"15011111111",
                    "question":"啊哈哈",
                    "answer":"服不服",
                    "role":0,
                    "createTime":1489719093000,
                    "updateTime":1513682138000
                }
            ],
            "firstPage": 1,
            "prePage": 0,
            "nextPage": 2,
            "lastPage": 6,
            "isFirstPage": true,
            "isLastPage": false,
            "hasPreviousPage": false,
            "hasNextPage": true,
            "navigatePages": 8,
            "navigatepageNums": [
              1,
              2,
              3,
              4,
              5,
              6
            ]
        }
    }
    

    参考:
    https://blog.csdn.net/zc_2016/article/details/88818789

  • 相关阅读:
    为App签名(为apk签名)
    Android如何获取网络连接状态(3G/Wifi)及怎样调用网络配置界面
    android textview改变部分文字的颜色和string.xml中文字的替换及部分内容设置颜色、字体、超链接、图片
    Toast和Looper。Handler消息循环机制
    android 创建DateTime类型的数据库
    Android中dp和px之间进行转换
    Java的ThreadPoolExecutor使用几点建议
    ListView中设置item点击状态的背景色
    android 让一个控件按钮居于底部的几种方法
    sqlite3数据类型和函数
  • 原文地址:https://www.cnblogs.com/chen-chen-chen/p/12295138.html
Copyright © 2020-2023  润新知