數據表結構設計
關係設計 java
爲何不用外鍵? 分庫分表有外鍵會很是麻煩,清洗數據也很麻煩。數據庫內置觸發器也不適合採用。mysql
查業務問題的後悔藥——時間戳 create_time 數據建立時間 update_time 數據更新時間 能夠用於查詢業務,主要要存儲datetime類型。算法
用戶模塊
用戶表 sql
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完成了惟一的驗證。數據庫
涉及知識點
- 橫向越權、縱向越權安全漏洞
橫向越權:攻擊者嘗試訪問與他擁有相同權限的用戶的資源 縱向越權:低級別攻擊者嘗試訪問高級別用戶的資源緩存
- 高複用服務響應對象的設計思想及抽象封裝
- 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九大內置對象架構
- 方法局部演進
功能模塊
接口設計
門戶_用戶接口
####1.登陸併發
/user/login.do post(代碼須要post方式請求),開放get,方便調試app
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 ] } }