改进...我也不知道改了什么...先存档一下吧

主要还是文件目录的调整
还有一些代码逻辑的修改
main
lensfrex 3 years ago
parent 5937135d8e
commit 4010cb8f09
Signed by: lensfrex
GPG Key ID: 0F69A0A2FBEE98A0
  1. 0
      front-end/404.html
  2. 45
      front-end/MaskDialogTest.html
  3. 0
      front-end/css/welcomepage.css
  4. 0
      front-end/images/54120216_p0_conpressed.jpg
  5. 1
      front-end/index.html
  6. 94
      front-end/js/events.js
  7. 0
      front-end/js/init.js
  8. 0
      front-end/js/jquery-3.6.0.min.js
  9. 0
      front-end/js/sha256-min.js
  10. 6
      front-end/js/utils.js
  11. 8
      front-end/js/welcomepage_message.js
  12. 53
      front-end/login.html
  13. 15
      src/main/java/me/lensfrex/littlebusters/RestTest.java
  14. 57
      src/main/java/me/lensfrex/littlebusters/api/v1/Register.java
  15. 8
      src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/LoginResponseData.java
  16. 22
      src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/RegisterResponseData.java
  17. 8
      src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/general/ResponseBase.java
  18. 13
      src/main/java/me/lensfrex/littlebusters/api/v1/beans/responses/general/ResponseCode.java
  19. 32
      src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserDao.java
  20. 4
      src/main/java/me/lensfrex/littlebusters/api/v1/dao/sql/KeyDaoInterface.java
  21. 8
      src/main/java/me/lensfrex/littlebusters/api/v1/dao/sql/UserDaoInterface.java
  22. 11
      src/main/java/me/lensfrex/littlebusters/api/v1/exceptions/RequestDataInvalidException.java
  23. 11
      src/main/java/me/lensfrex/littlebusters/api/v1/exceptions/user/LoginInfoWrongException.java
  24. 15
      src/main/java/me/lensfrex/littlebusters/api/v1/inputTest.java
  25. 20
      src/main/java/me/lensfrex/littlebusters/api/v1/service/FeedBack.java
  26. 4
      src/main/java/me/lensfrex/littlebusters/api/v1/service/Index.java
  27. 47
      src/main/java/me/lensfrex/littlebusters/api/v1/service/login/Login.java
  28. 68
      src/main/java/me/lensfrex/littlebusters/api/v1/service/register/Register.java
  29. 19
      src/main/java/me/lensfrex/littlebusters/api/v1/service/token/TokenChecker.java
  30. 16
      src/main/java/me/lensfrex/littlebusters/api/v1/service/token/TokenRefresher.java
  31. 14
      src/main/java/me/lensfrex/littlebusters/api/v1/utils/database/User.java
  32. 23
      src/main/java/me/lensfrex/littlebusters/api/v1/utils/jwt/JWTManager.java
  33. 2
      src/main/resources/mappers/DatabaseInitSqlMapper.xml
  34. 2
      src/main/resources/mappers/KeySqlMapper.xml
  35. 13
      src/main/resources/mappers/LoginSqlMapper.xml
  36. 12
      src/main/resources/mappers/RegisterSqlMapper.xml
  37. 26
      src/main/resources/mappers/UserSqlMapper.xml
  38. 28
      src/main/webapp/js/events.js

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>欢迎 - LittleBusters</title>
<link rel="stylesheet" type="text/css" href="css\welcomepage.css">
<script src="js/welcomepage_message.js"></script>
<!--[if IE]><script>alert("别用IE浏览器啦,快换一个吧!");</script><![endif]-->
</head>
<!-- 前端不擅长,逻辑做的很简单,见谅 ( ̄﹏ ̄;)-->
<body lang="ZH-CN">
<div id="content">
<div id="background"></div>
<div id="dialogMask" onclick="closeDialog()"></div>
<div class="login-box">
<div class="login-box-title">登录/注册</div>
<div class="input-field-group">
<div class="input-field">
<input id="username" type="text" autocomplete="username" placeholder="用户名/UID">
</div>
<div class="input-field">
<input id="passwd" type="password" autocomplete="current-password" placeholder="密码">
</div>
</div>
<div class="operator-box">
<button class="big-button" type="submit" id="login-botton" onclick="checkInputCorrect()">登录</button>
<div class="rl-layout-box">
<a class="small-link" onclick="forgotPasswd()">不记得密码了?</a>
<a class="small-link">没有账号?注册一个!</a>
</div>
</div>
</div>
</div>
</body>
</html>

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

@ -20,6 +20,7 @@
</head> </head>
<!-- 前端不擅长,逻辑做的很简单,见谅 ( ̄﹏ ̄;) --> <!-- 前端不擅长,逻辑做的很简单,见谅 ( ̄﹏ ̄;) -->
<!-- 急招前端ing..... -->
<body lang="ZH-CN"> <body lang="ZH-CN">
<div id="content"> <div id="content">

@ -0,0 +1,94 @@
function login() {
username = $("#username").val();
password = $("#passwd").val();
if (!checkInputDataCorrect(username, password)) {
return;
}
encPassword = encryptPassword(password);
postData = {
"user_name": username,
"password": encPassword
};
$.ajax({
url: "/api/v1/login",
type: "post",
dataType: "json",
data: JSON.stringify(postData),
success: (result) => {
console.log("获取到数据:" + JSON.stringify(result));
resultCode = result.code;
switch(resultCode) {
case 1:
showMessage("好啦");
storeToken(result.data.access_token);
break;
case 2:
showMessage("请求的数据不对哦");
break;
case 3:
showMessage("密码或用户名不正确...");
break;
case -1:
showMessage("哦豁,有个家伙写BUG了");
break;
default :
showMessage("出现了不知道什么原因的错误,应给是服务器那边的锅")
}
},
error: (msg, status) => {
console.log(msg.status);
showMessage("登录时发生错误:" + status + " " + msg.status);
}
})
}
function register() {
username = $("#username").val();
password = $("#passwd").val();
if (!checkInputDataCorrect(username, password)) {
return;
}
encPassword = encryptPassword(password);
postData = {
"user_name": username,
"password": encPassword
};
$.ajax({
url: "/api/v1/register",
type: "post",
dataType: "json",
data: JSON.stringify(postData),
success: (result) => {
console.log("获取到数据:" + JSON.stringify(result));
resultCode = result.code;
switch(resultCode) {
case 1:
showMessage("好啦");
storeToken(result.data.access_token);
break;
case 2:
showMessage("请求的数据不对哦");
break;
case 4:
showMessage("用户名已经被别人用啦");
break;
case -1:
showMessage("哦豁,有个家伙写BUG了");
break;
default :
showMessage("出现了不知道什么原因的错误,应给是服务器那边的锅")
}
},
error: (msg, status) => {
console.log(msg.status);
showMessage("注册时发生错误:" + status + " " + msg.status);
}
})
}

@ -24,5 +24,9 @@ function isNormalCharacter(source) {
function encryptPassword(password) { function encryptPassword(password) {
sha256 = CryptoJS.SHA256; sha256 = CryptoJS.SHA256;
return sha256(sha256(password).toString()).toString(); return sha256(sha256(password).toString() + password).toString();
}
function storeToken(token) {
localStorage.setItem("access_token", token);
} }

@ -2,10 +2,6 @@ function forgotPasswd() {
showDialog("( ̄﹏ ̄;)", "欸这个嘛...我还没做完呢...( ̄﹏ ̄;)"); showDialog("( ̄﹏ ̄;)", "欸这个嘛...我还没做完呢...( ̄﹏ ̄;)");
} }
function register() {
showDialog("( ̄﹏ ̄;)", "欸这个嘛...我还没做完呢...( ̄﹏ ̄;)");
}
function closeDialog() { function closeDialog() {
$("#dialogMask").fadeOut(400); $("#dialogMask").fadeOut(400);
} }
@ -32,6 +28,10 @@ function showMessage(message) {
$("#errMsgBox")[0].innerHTML = `<p>${message}</p>`; $("#errMsgBox")[0].innerHTML = `<p>${message}</p>`;
} }
function clearMessage() {
$("#errMsgBox")[0].innerHTML = ``;
}
function showDialog(title, message) { function showDialog(title, message) {
html = `<div class="dialogContentBox"> html = `<div class="dialogContentBox">
<div class="titleBox"> <div class="titleBox">

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>欢迎 - LittleBusters</title>
<link rel="stylesheet" type="text/css" href="css\welcomepage.css">
<script src="js/sha256-min.js"></script>
<script src="js/jquery-3.6.0.min.js"></script>
<script src="js/utils.js"></script>
<script src="js/welcomepage_message.js"></script>
<script src="js/events.js"></script>
<script src="js/init.js"></script>
<!--[if IE]><script>alert("别用IE浏览器啦,快换一个吧!");</script><![endif]-->
</head>
<!-- 前端不擅长,逻辑做的很简单,见谅 ( ̄﹏ ̄;) -->
<!-- 急招前端ing..... -->
<body lang="ZH-CN">
<div id="content">
<div id="background"></div>
<div id="dialogMask"></div>
<div class="login-box">
<div class="login-box-title">登录/注册</div>
<div class="input-field-group">
<div class="input-field">
<input id="username" type="text" autocomplete="username" placeholder="用户名/UID">
</div>
<div class="input-field">
<input id="passwd" type="password" autocomplete="current-password" placeholder="密码">
</div>
<div id="errMsgBox"></div>
</div>
<div class="operator-box">
<div class="botton-box">
<button class="big-button" type="submit" id="register-botton">注册</button>
<button class="big-button" type="submit" id="login-botton">登录</button>
</div>
<div class="rl-layout-box">
<a class="small-link" id="forgotPasswordLabel">不记得密码了?</a>
</div>
</div>
</div>
</div>
</body>
</html>

@ -1,15 +0,0 @@
package me.lensfrex.littlebusters;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/lb")
public class RestTest {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getMessage() {
return "ASJKDFHYG";
}
}

@ -1,57 +0,0 @@
package me.lensfrex.littlebusters.api.v1;
import com.google.gson.Gson;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import me.lensfrex.littlebusters.api.v1.beans.requests.RegisterRequestBody;
import me.lensfrex.littlebusters.api.v1.dao.UserOperators;
import me.lensfrex.littlebusters.api.v1.beans.responses.RegisterResponseData;
import me.lensfrex.littlebusters.api.v1.beans.responses.general.ErrorResponse;
import me.lensfrex.littlebusters.api.v1.beans.responses.general.ResponseBase;
import me.lensfrex.littlebusters.api.v1.utils.InputChecker;
import me.lensfrex.littlebusters.api.v1.utils.database.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.mindrot.jbcrypt.BCrypt;
import java.util.UUID;
@Path("/register")
public class Register {
private final static Gson gson = new Gson();
@POST
@Produces(MediaType.APPLICATION_JSON)
public String register(String request) {
System.out.println("Start register.");
RegisterRequestBody registerRequestBody;
try {
registerRequestBody = gson.fromJson(request, RegisterRequestBody.class);
if (InputChecker.hasInvalidChar(registerRequestBody.getUserName()) ||
InputChecker.hasInvisibleChar(registerRequestBody.getPassword())) {
ErrorResponse errorResponse = new ErrorResponse(1, "用户名或密码非法");
return gson.toJson(errorResponse);
}
} catch (Exception e) {
System.err.println(request);
ErrorResponse errorResponse = new ErrorResponse(2, "请求的数据格式不对");
return gson.toJson(errorResponse);
}
String userUUID = UUID.randomUUID().toString();
String userBcryptPasswd = BCrypt.hashpw(registerRequestBody.getPassword(), BCrypt.gensalt());
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
UserOperators userOperators = sqlSession.getMapper(UserOperators.class);
userOperators.addRegisterInfoIntoDb(userUUID, registerRequestBody.getUserName(), userBcryptPasswd);
RegisterResponseData registerResponseBody = new RegisterResponseData(10101, userUUID, userBcryptPasswd);
ResponseBase<RegisterResponseData> response = new ResponseBase<>(200, "success", registerResponseBody);
return gson.toJson(response);
}
}

@ -23,9 +23,9 @@ public class LoginResponseData {
* 用户此次得到的token的过期时间 * 用户此次得到的token的过期时间
*/ */
@SerializedName("expired_at") @SerializedName("expired_at")
private String expiredAt; private long expiredAt;
public LoginResponseData(long uid, String uuid, String accessToken, String expiredAt) { public LoginResponseData(long uid, String uuid, String accessToken, long expiredAt) {
this.uid = uid; this.uid = uid;
this.uuid = uuid; this.uuid = uuid;
this.accessToken = accessToken; this.accessToken = accessToken;
@ -56,11 +56,11 @@ public class LoginResponseData {
this.accessToken = accessToken; this.accessToken = accessToken;
} }
public String getExpiredAt() { public long getExpiredAt() {
return expiredAt; return expiredAt;
} }
public void setExpiredAt(String expiredAt) { public void setExpiredAt(long expiredAt) {
this.expiredAt = expiredAt; this.expiredAt = expiredAt;
} }
} }

@ -8,6 +8,11 @@ public class RegisterResponseData {
*/ */
private int uid; private int uid;
/**
* 用户注册分派到的uuid
*/
private String UUID;
/** /**
* 用户本次注册时得到的token * 用户本次注册时得到的token
*/ */
@ -18,10 +23,11 @@ public class RegisterResponseData {
* 用户此次得到的token的过期时间 * 用户此次得到的token的过期时间
*/ */
@SerializedName("expired_at") @SerializedName("expired_at")
private String expiredAt; private long expiredAt;
public RegisterResponseData(int uid, String accessToken, String expiredAt) { public RegisterResponseData(int uid, String UUID, String accessToken, long expiredAt) {
this.uid = uid; this.uid = uid;
this.UUID = UUID;
this.accessToken = accessToken; this.accessToken = accessToken;
this.expiredAt = expiredAt; this.expiredAt = expiredAt;
} }
@ -34,6 +40,14 @@ public class RegisterResponseData {
this.uid = uid; this.uid = uid;
} }
public String getUUID() {
return UUID;
}
public void setUUID(String UUID) {
this.UUID = UUID;
}
public String getAccessToken() { public String getAccessToken() {
return accessToken; return accessToken;
} }
@ -42,11 +56,11 @@ public class RegisterResponseData {
this.accessToken = accessToken; this.accessToken = accessToken;
} }
public String getExpiredAt() { public long getExpiredAt() {
return expiredAt; return expiredAt;
} }
public void setExpiredAt(String expiredAt) { public void setExpiredAt(long expiredAt) {
this.expiredAt = expiredAt; this.expiredAt = expiredAt;
} }
} }

@ -50,4 +50,12 @@ public class ResponseBase<T> {
public void setData(T data) { public void setData(T data) {
this.data = data; this.data = data;
} }
public static<S> ResponseBase<S> success(S data) {
return new ResponseBase<>(ResponseCode.SUCCESS, "success", data);
}
public static<S> ResponseBase<S> error(int responseCode, String message) {
return new ResponseBase<>(responseCode, message, null);
}
} }

@ -0,0 +1,13 @@
package me.lensfrex.littlebusters.api.v1.beans.responses.general;
public class ResponseCode {
public final static int SERVER_ERROR = -1;
public final static int SUCCESS = 1;
public final static int REQUEST_FORMAT_INVALID = 2;
public final static int PASSWORD_WRONG = 3;
public final static int USER_ALREADY_EXISTS = 4;
public final static int LOGIN_DATA_INVALID = 5;
public final static int TOKEN_INVALID = 6;
}

@ -0,0 +1,32 @@
package me.lensfrex.littlebusters.api.v1.dao;
import me.lensfrex.littlebusters.api.v1.dao.sql.UserDaoInterface;
import me.lensfrex.littlebusters.api.v1.pojos.UserInformation;
import me.lensfrex.littlebusters.api.v1.utils.database.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
public class UserDao {
public static UserInformation getUser(String userName) {
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
UserDaoInterface mapper = sqlSession.getMapper(UserDaoInterface.class);
return mapper.getBasicInfoByUserName(userName);
}
public static boolean isUserAlreadyExist(String userName) {
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
UserDaoInterface mapper = sqlSession.getMapper(UserDaoInterface.class);
return mapper.isUserNameAlreadyExists(userName);
}
public static int addUser(String UUID, String userName, String password) {
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
UserDaoInterface mapper = sqlSession.getMapper(UserDaoInterface.class);
return mapper.addRegisterInfoIntoDb(UUID, userName, password);
}
}

@ -1,8 +1,8 @@
package me.lensfrex.littlebusters.api.v1.dao; package me.lensfrex.littlebusters.api.v1.dao.sql;
import me.lensfrex.littlebusters.api.v1.pojos.StoredKey; import me.lensfrex.littlebusters.api.v1.pojos.StoredKey;
public interface KeyDatabase { public interface KeyDaoInterface {
StoredKey getKeyContentByKeyName(String keyName); StoredKey getKeyContentByKeyName(String keyName);
int addKeyIntoDatabase(String keyContent, String keyName, int keyType); int addKeyIntoDatabase(String keyContent, String keyName, int keyType);

@ -1,12 +1,16 @@
package me.lensfrex.littlebusters.api.v1.dao; package me.lensfrex.littlebusters.api.v1.dao.sql;
import me.lensfrex.littlebusters.api.v1.pojos.UserInformation; import me.lensfrex.littlebusters.api.v1.pojos.UserInformation;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
public interface UserOperators { public interface UserDaoInterface {
boolean isUserNameAlreadyExists(@Param("userName") String userName);
int addRegisterInfoIntoDb(@Param("uuid") String UUID, int addRegisterInfoIntoDb(@Param("uuid") String UUID,
@Param("userName") String userName, @Param("userName") String userName,
@Param("password") String password); @Param("password") String password);
UserInformation getBasicInfoByUserName(@Param("userName") String userName); UserInformation getBasicInfoByUserName(@Param("userName") String userName);
} }

@ -0,0 +1,11 @@
package me.lensfrex.littlebusters.api.v1.exceptions;
public class RequestDataInvalidException extends Exception {
public RequestDataInvalidException(String message) {
super(message);
}
public RequestDataInvalidException() {
super("请求的数据有误");
}
}

@ -0,0 +1,11 @@
package me.lensfrex.littlebusters.api.v1.exceptions.user;
public class LoginInfoWrongException extends Exception {
public LoginInfoWrongException(String message) {
super(message);
}
public LoginInfoWrongException() {
super("用户名或密码错误");
}
}

@ -1,15 +0,0 @@
package me.lensfrex.littlebusters.api.v1;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/inputTest")
public class inputTest {
@POST
@Produces(MediaType.APPLICATION_JSON)
public String inputTest(String string) {
return string;
}
}

@ -0,0 +1,20 @@
package me.lensfrex.littlebusters.api.v1.service;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
/**
* 只是方便前端测试自己到底发了什么数据给后端
* 返回数据不是很详细只是把数据体原样给返回了
* 但是header信息之类的并没有提供
*/
@Path("/test")
public class FeedBack {
@POST
@Produces(MediaType.TEXT_PLAIN)
public String returnRequest(String string) {
return string;
}
}

@ -1,4 +1,4 @@
package me.lensfrex.littlebusters; package me.lensfrex.littlebusters.api.v1.service;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path; import jakarta.ws.rs.Path;
@ -6,7 +6,7 @@ import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
@Path("/") @Path("/")
public class ApiIndex { public class Index {
@GET @GET
@Produces(MediaType.TEXT_HTML) @Produces(MediaType.TEXT_HTML)
public String index() { public String index() {

@ -1,4 +1,4 @@
package me.lensfrex.littlebusters.api.v1.login; package me.lensfrex.littlebusters.api.v1.service.login;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
@ -10,20 +10,22 @@ import me.lensfrex.littlebusters.api.v1.beans.requests.LoginRequestBody;
import me.lensfrex.littlebusters.api.v1.beans.responses.LoginResponseData; import me.lensfrex.littlebusters.api.v1.beans.responses.LoginResponseData;
import me.lensfrex.littlebusters.api.v1.beans.responses.general.ErrorResponse; import me.lensfrex.littlebusters.api.v1.beans.responses.general.ErrorResponse;
import me.lensfrex.littlebusters.api.v1.beans.responses.general.ResponseBase; import me.lensfrex.littlebusters.api.v1.beans.responses.general.ResponseBase;
import me.lensfrex.littlebusters.api.v1.beans.responses.general.ResponseCode;
import me.lensfrex.littlebusters.api.v1.exceptions.user.LoginInfoWrongException;
import me.lensfrex.littlebusters.api.v1.pojos.UserInformation; import me.lensfrex.littlebusters.api.v1.pojos.UserInformation;
import me.lensfrex.littlebusters.api.v1.utils.InputChecker; import me.lensfrex.littlebusters.api.v1.utils.InputChecker;
import me.lensfrex.littlebusters.api.v1.utils.database.User; import me.lensfrex.littlebusters.api.v1.dao.UserDao;
import me.lensfrex.littlebusters.api.v1.utils.jwt.JWTManager; import me.lensfrex.littlebusters.api.v1.utils.jwt.JWTManager;
import org.mindrot.jbcrypt.BCrypt; import org.mindrot.jbcrypt.BCrypt;
import java.time.LocalDateTime; import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
@Path("/login") @Path("/login")
public class Login { public class Login {
private final static int TOKEN_EXPIRE_DAY = 15; private static final Gson gson = new Gson();
private final static Gson gson = new Gson(); private static final JWTManager jwtManager = JWTManager.getInstance();
private final static JWTManager jwtManager = new JWTManager();
User userTools = new User();
@POST @POST
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@ -38,43 +40,34 @@ public class Login {
return gson.toJson(errorResponse); return gson.toJson(errorResponse);
} }
UserInformation userDatabaseInformation = userTools.getUser(loginRequestBody.getUserName()); UserInformation userDatabaseInformation = UserDao.getUser(loginRequestBody.getUserName());
// todo 这些情况用异常处理会好点吧 分散在代码里面很难看
// 过会改改
if (userDatabaseInformation == null) { if (userDatabaseInformation == null) {
ErrorResponse errorResponse = new ErrorResponse(400, "用户名或密码错误"); throw new LoginInfoWrongException();
return gson.toJson(errorResponse);
} }
if (!identifyPassword(loginRequestBody.getPassword(), userDatabaseInformation.password)) { if (!identifyPassword(loginRequestBody.getPassword(), userDatabaseInformation.password)) {
ErrorResponse errorResponse = new ErrorResponse(400, "用户名或密码错误"); throw new LoginInfoWrongException();
return gson.toJson(errorResponse);
} }
String userToken = jwtManager.createNewJWT("login", loginRequestBody.getUserName(), TOKEN_EXPIRE_DAY); Date expireDate = Date.from(Instant.now().plus(JWTManager.TOKEN_DEFAULT_EXPIRE_DAY, ChronoUnit.DAYS));
String userToken = jwtManager.createNewJWT(loginRequestBody.getUserName(), expireDate);
LoginResponseData loginResponseData = new LoginResponseData( LoginResponseData loginResponseData = new LoginResponseData(
userDatabaseInformation.uid, userDatabaseInformation.uid,
userDatabaseInformation.uuid, userDatabaseInformation.uuid,
userToken, userToken,
LocalDateTime.now().plusDays(TOKEN_EXPIRE_DAY).toString()); expireDate.getTime());
ResponseBase<LoginResponseData> response = new ResponseBase<>(200, "success", loginResponseData); ResponseBase<LoginResponseData> response = ResponseBase.success(loginResponseData);
return gson.toJson(response); return gson.toJson(response);
} catch (JsonParseException e) { } catch (JsonParseException e) {
System.err.println(request); return gson.toJson(ResponseBase.error(ResponseCode.REQUEST_FORMAT_INVALID, "请求的数据格式不对"));
} catch (LoginInfoWrongException e) {
ErrorResponse errorResponse = new ErrorResponse(300, "请求的数据格式不对"); return gson.toJson(ResponseBase.error(ResponseCode.PASSWORD_WRONG, "用户名或密码错误"));
return gson.toJson(errorResponse);
} catch (Exception e) { } catch (Exception e) {
System.err.println(request); return gson.toJson(ResponseBase.error(ResponseCode.SERVER_ERROR, "服务器内部错误,请联系那个背锅的家伙"));
System.err.println(e.getMessage());
ErrorResponse errorResponse = new ErrorResponse(400, "服务器内部错误,请联系那个背锅的家伙");
return gson.toJson(errorResponse);
} }
} }

@ -0,0 +1,68 @@
package me.lensfrex.littlebusters.api.v1.service.register;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import me.lensfrex.littlebusters.api.v1.beans.requests.RegisterRequestBody;
import me.lensfrex.littlebusters.api.v1.beans.responses.general.ResponseCode;
import me.lensfrex.littlebusters.api.v1.beans.responses.RegisterResponseData;
import me.lensfrex.littlebusters.api.v1.beans.responses.general.ResponseBase;
import me.lensfrex.littlebusters.api.v1.dao.UserDao;
import me.lensfrex.littlebusters.api.v1.exceptions.RequestDataInvalidException;
import me.lensfrex.littlebusters.api.v1.utils.InputChecker;
import me.lensfrex.littlebusters.api.v1.utils.jwt.JWTManager;
import org.mindrot.jbcrypt.BCrypt;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.UUID;
@Path("/register")
public class Register {
private static final JWTManager jwtManager = JWTManager.getInstance();
private static final Gson gson = new Gson();
@POST
@Produces(MediaType.APPLICATION_JSON)
public String register(String request) {
RegisterRequestBody registerRequestBody;
try {
registerRequestBody = gson.fromJson(request, RegisterRequestBody.class);
if (registerRequestBody == null ||
InputChecker.hasInvalidChar(registerRequestBody.getUserName()) ||
InputChecker.hasInvisibleChar(registerRequestBody.getPassword())) {
throw new RequestDataInvalidException();
}
if (UserDao.isUserAlreadyExist(registerRequestBody.getUserName())) {
return gson.toJson(ResponseBase.error(ResponseCode.USER_ALREADY_EXISTS, "申请注册的用户已经存在"));
}
String userUUID = UUID.randomUUID().toString();
String userBcryptPasswd = BCrypt.hashpw(registerRequestBody.getPassword(), BCrypt.gensalt());
int newUid = UserDao.addUser(userUUID, registerRequestBody.getUserName(), userBcryptPasswd);
Date expireDate = Date.from(Instant.now().plus(JWTManager.TOKEN_DEFAULT_EXPIRE_DAY, ChronoUnit.DAYS));
RegisterResponseData registerResponseBody = new RegisterResponseData(
newUid,
userUUID,
jwtManager.createNewJWT(registerRequestBody.getUserName(), expireDate),
expireDate.getTime());
return gson.toJson(ResponseBase.success(registerResponseBody));
} catch (JsonParseException | RequestDataInvalidException e) {
return gson.toJson(ResponseBase.error(ResponseCode.REQUEST_FORMAT_INVALID, "请求的数据不正确"));
} catch (Exception e) {
return gson.toJson(ResponseBase.error(ResponseCode.SERVER_ERROR, "服务器程序发生错误,有个家伙又写bug了。Error:" + e.getMessage()));
}
}
}

@ -0,0 +1,19 @@
package me.lensfrex.littlebusters.api.v1.service.token;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import me.lensfrex.littlebusters.api.v1.utils.jwt.JWTManager;
@Path("/token")
public class TokenChecker {
public static final JWTManager jwtManager = JWTManager.getInstance();
@POST
@Path("/check")
@Produces(MediaType.APPLICATION_JSON)
public String checkTokenAvailable(String request) {
return String.valueOf(jwtManager.verifyToken(request));
}
}

@ -0,0 +1,16 @@
package me.lensfrex.littlebusters.api.v1.service.token;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/token")
public class TokenRefresher {
@Path("/refresh")
@POST
@Produces(MediaType.APPLICATION_JSON)
public String refreshToken(String request) {
return request;
}
}

@ -1,14 +0,0 @@
package me.lensfrex.littlebusters.api.v1.utils.database;
import me.lensfrex.littlebusters.api.v1.dao.UserOperators;
import me.lensfrex.littlebusters.api.v1.pojos.UserInformation;
import org.apache.ibatis.session.SqlSession;
public class User {
public UserInformation getUser(String userName) {
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
UserOperators mapper = sqlSession.getMapper(UserOperators.class);
return mapper.getBasicInfoByUserName(userName);
}
}

@ -2,34 +2,43 @@ package me.lensfrex.littlebusters.api.v1.utils.jwt;
import io.jsonwebtoken.*; import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys; import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;
import me.lensfrex.littlebusters.api.v1.utils.Time;
import java.security.Key; import java.security.Key;
import java.time.LocalDateTime; import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class JWTManager { public class JWTManager {
public static final int TOKEN_DEFAULT_EXPIRE_DAY = 15;
// todo 时间有限先这样写能跑起来吧 // todo 时间有限先这样写能跑起来吧
// todo 第一次生成之后应该存到数据库里边去的
// todo 这样写的话每一次启动都是不同的密钥,已经生成的密钥会失效的
private final static Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); private final static Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
public String createNewJWT(String subject, String user, int invalidDays) { private final static JWTManager self = new JWTManager();
private JWTManager() {}
public static JWTManager getInstance() {
return self;
}
public String createNewJWT(String user, Date invalidDate) {
Map<String, Object> header = new HashMap<>(); Map<String, Object> header = new HashMap<>();
header.put("alg", "HS256"); header.put("alg", "HS256");
header.put("typ", "JWT"); header.put("typ", "JWT");
LocalDateTime now = Time.getNowDayTime(); LocalDate now = LocalDate.now();
Map<String, Object> payload = new HashMap<>(); Map<String, Object> payload = new HashMap<>();
payload.put("user", user); payload.put("user", user);
payload.put("start", now.toString());
payload.put("exp", now.plusDays(invalidDays).toString());
payload.put("api_ver", "1"); payload.put("api_ver", "1");
// payload.put("iss", machineId); // payload.put("iss", machineId);
return Jwts.builder() return Jwts.builder()
.setHeader(header) .setHeader(header)
.setClaims(payload) .setClaims(payload)
.setExpiration(invalidDate)
.signWith(key) .signWith(key)
.compact(); .compact();

@ -4,7 +4,7 @@
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="me.lensfrex.littlebusters.api.v1.dao.KeyDatabase"> <mapper namespace="me.lensfrex.littlebusters.api.v1.dao.sql.KeyDaoInterface">
<sql id="createDatabaseTables"> <sql id="createDatabaseTables">
CREATE TABLE `account_basic` ( CREATE TABLE `account_basic` (
`uid` int(18) unsigned unique NOT NULL AUTO_INCREMENT COMMENT '用户id,1起,给人看的', `uid` int(18) unsigned unique NOT NULL AUTO_INCREMENT COMMENT '用户id,1起,给人看的',

@ -4,7 +4,7 @@
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="me.lensfrex.littlebusters.api.v1.dao.KeyDatabase"> <mapper namespace="me.lensfrex.littlebusters.api.v1.dao.sql.KeyDaoInterface">
<select id="getKeyContentByKeyName" resultType="me.lensfrex.littlebusters.api.v1.pojos.StoredKey" <select id="getKeyContentByKeyName" resultType="me.lensfrex.littlebusters.api.v1.pojos.StoredKey"
parameterType="java.lang.String"> parameterType="java.lang.String">
select key_content as keyContent, key_name as keyName, key_type as keyType select key_content as keyContent, key_name as keyName, key_type as keyType

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="me.lensfrex.littlebusters.api.v1.dao.UserOperators">
<select id="getBasicInfoByUserName" resultType="me.lensfrex.littlebusters.api.v1.pojos.UserInformation" parameterType="java.lang.String">
select uid, uuid, passwd as password, deleted, account_status as accountStstus
from `account_basic`
where user_name = #{userName}
</select>
</mapper>

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="me.lensfrex.littlebusters.api.v1.dao.UserOperators">
<insert id="addRegisterInfoIntoDb">
insert into `LittleBusters`.`account_basic` (`uuid`, `user_name`, `passwd`)
values (#{uuid}, #{userName}, #{password})
</insert>
</mapper>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="me.lensfrex.littlebusters.api.v1.dao.sql.UserDaoInterface">
<select id="getBasicInfoByUserName" resultType="me.lensfrex.littlebusters.api.v1.pojos.UserInformation" parameterType="java.lang.String">
select uid, uuid, passwd as password, deleted, account_status as accountStstus
from `account_basic`
where user_name = #{userName}
</select>
<select id="isUserNameAlreadyExists" resultType="boolean" parameterType="java.lang.String">
select exists(select 1 from `account_basic` where user_name = #{userName})
</select>
<insert id="addRegisterInfoIntoDb" useGeneratedKeys="true" keyProperty="uid">
insert into `LittleBusters`.`account_basic` (`uuid`, `user_name`, `passwd`)
values (#{uuid}, #{userName}, #{password})
<selectKey keyProperty="uid" order="AFTER" resultType="int">
select LAST_INSERT_ID();
</selectKey>
</insert>
</mapper>

@ -1,28 +0,0 @@
function login() {
console.log("start login");
username = $("#username").val();
password = $("#passwd").val();
if (!checkInputDataCorrect(username, password)) {
return;
}
encPassword = encryptPassword(password);
postData = {
"user_name": username,
"password": encPassword
};
$.ajax({
url: "/api/v1/login",
type: "post",
dataType: "json",
data: JSON.stringify(postData),
success: (result) => {
showDialog("Test", "获取到数据:" + JSON.stringify(result));
},
error: (msg, status) => {
showMessage("登陆时发生错误:",JSON.stringify(msg));
}
})
}
Loading…
Cancel
Save