Compare commits
3 Commits
main
...
spring-dev
Author | SHA1 | Date |
---|---|---|
lensfrex | a9fd0c1dfb | 3 years ago |
lensfrex | 207a8caf21 | 3 years ago |
lensfrex | 2a4228d0e1 | 3 years ago |
@ -0,0 +1,172 @@ |
||||
# Trailblazer RESTful API 文档 |
||||
|
||||
--- |
||||
|
||||
##### 本文档中,除非特殊说明,URL地址前缀均为 http://[server_address]:[port]/ (本地运行),如果使用 lb.ciduid.top 提供的api服务,则应该为 https://lb.ciduid.top/api/v1/ |
||||
|
||||
##### 例如:登录接口`https://localhost:64888/user/login`(本地运行) `https://lb.ciduid.top/api/v1/user/login` (使用lb.ciduid.top的api) |
||||
|
||||
##### POST方法的API参数均为Body部分的参数,以json格式发送 |
||||
|
||||
--- |
||||
|
||||
## 用户相关 |
||||
|
||||
### 1. 登录 |
||||
|
||||
- 功能:登录一个已经存在的用户,获取会话token |
||||
|
||||
- URL: `/user/login` |
||||
|
||||
- 方法:`POST` |
||||
|
||||
- 参数: |
||||
|
||||
| 参数 | 参数类型 | 说明 | |
||||
| --------- | ------ | ---------------------------------------- | |
||||
| user_name | string | 登录用户名,必选 | |
||||
| password | string | 一次sha256后,再在尾部拼接原始密码,然后再一次sha256得到的密文,必选 | |
||||
| verify | string | 验证码,可选,在服务器要求的时候需要提供,目前没有用 | |
||||
|
||||
示例: |
||||
|
||||
```json |
||||
{ |
||||
"user_name": "userName", |
||||
"password": "57a8a929b8fc077da76769179159a1d3ae44e9f255c270fc98d4b125b30d5cca", |
||||
"verify": "114514" |
||||
} |
||||
``` |
||||
|
||||
- 返回: |
||||
|
||||
- | 字段 | 字段类型 | 说明 | |
||||
| ------------ | ------ | ------------------------------------------- | |
||||
| code | int | 请求的状态信息码,详见“状态信息码” | |
||||
| msg | string | 本次请求的信息 | |
||||
| uid | int | 用户的uid | |
||||
| access_token | string | 会话token,用于其他API调用,成功时返回正确token,不成功时为null | |
||||
| expired_at | string | token过期时间,应当在token过期前调用token续期API以获取新的token | |
||||
|
||||
### 2. 注册 |
||||
|
||||
- 功能:注册创建一个账号 |
||||
|
||||
- URL:`/user/register` |
||||
|
||||
- 方法:`POST` |
||||
|
||||
- 参数: |
||||
|
||||
| 参数 | 参数类型 | 说明 | |
||||
| --------- | ------ | -------------------------------------------------- | |
||||
| user_name | string | 注册的用户名,用于登录,最长不超过32位,必选 | |
||||
| password | string | 第一次sha256后再在尾部拼接原始密码,然后再一次sha256得到的密文,长度应为8~32位,必选 | |
||||
| verify | string | 验证码,可选,在服务器要求的时候需要提供,目前没有用 | |
||||
|
||||
示例: |
||||
|
||||
```json |
||||
{ |
||||
"user_name": "userName", |
||||
"password": "57a8a929b8fc077da76769179159a1d3ae44e9f255c270fc98d4b125b30d5cca", |
||||
"verify": "114514" |
||||
} |
||||
``` |
||||
|
||||
- 返回: |
||||
|
||||
- | 字段 | 字段类型 | 说明 | |
||||
| ---------- | ------ | ------------------------------------------- | |
||||
| code | int | 请求的状态信息码,详见“状态信息码” | |
||||
| msg | string | 本次请求的信息 | |
||||
| uid | int | 用户uid | |
||||
| token | string | 会话token,用于其他API调用,成功时返回正确token,不成功时为null | |
||||
| expired_at | string | token过期时间,应当在token过期前调用token续期API以获取新的token | |
||||
|
||||
### 3. 修改用户基本信息 |
||||
|
||||
// 这里的接口还没想好怎么设计,所以没写完 |
||||
|
||||
- 功能:修改用户的基本信息,如密码、登录名等 |
||||
|
||||
- URL:`/user/modifyUserBasicInfo?uid={uid}` |
||||
|
||||
- 方法:`post` |
||||
|
||||
- 参数: |
||||
|
||||
- | 参数 | 参数类型 | 说明 | |
||||
| --------- | ------ | ----------------------- | |
||||
| uid | int | 欲修改的用户的uid,必选 | |
||||
| user_name | string | 注册的用户名,用于登录,最长不超过32位,必选 | |
||||
| token | string | 登陆时获得的token,必选 | |
||||
|
||||
示例: |
||||
|
||||
```json |
||||
{ |
||||
"user_name": "userName", |
||||
"token": "57a8a929b8fc077da76769179159a1d3ae44e9f255c270fc98d4b125b30d5cca", "" |
||||
|
||||
} |
||||
``` |
||||
|
||||
### 4. 修改用户个性信息 |
||||
|
||||
- 功能:修改用户的基本信息,如密码、登录名等 |
||||
|
||||
- URL:`/user/modifyUserInfo?uid={uid}` |
||||
|
||||
- 方法:`post` |
||||
|
||||
- 参数: |
||||
|
||||
- | 参数 | 参数类型 | 说明 | |
||||
| ------------ | ------ | ------------------------- | |
||||
| uid | int | 欲修改的用户的uid,放置于请求URL参数中,必选 | |
||||
| token | string | 有效的会话token,必选 | |
||||
| modify_tiems | json | 欲更改的个性数据信息 | |
||||
|
||||
- 返回: |
||||
|
||||
- | 字段 | 字段类型 | 说明 | |
||||
| ------ | --------- | ------------ | |
||||
| code | int | 状态信息码 | |
||||
| msg | string | 结果信息 | |
||||
| result | jsonArray | 更改后用户的完整个性信息 | |
||||
|
||||
### 5. 获取用户个性信息 |
||||
|
||||
- 功能:修改用户的基本信息,如密码、登录名等 |
||||
|
||||
- URL:`/user/profile?uid={uid}` |
||||
|
||||
- 方法:`get` |
||||
|
||||
- 参数: |
||||
|
||||
- | 参数 | 参数类型 | 说明 | |
||||
| ----- | ------ | --------------------------- | |
||||
| uid | int | 欲获取的用户的uid,放置于请求URL参数中,必选 | |
||||
| token | string | 有效的会话token,可选,若不提供仅能显示公开的信息 | |
||||
|
||||
- 返回: |
||||
|
||||
- | 字段 | 字段类型 | 说明 | |
||||
| ------ | --------- | ------ | |
||||
| code | int | 状态信息码 | |
||||
| msg | string | 结果信息 | |
||||
| result | jsonArray | 获取到的信息 | |
||||
|
||||
> 4、5中用户信息result字段的json结构: |
||||
> |
||||
> ```json |
||||
> [ |
||||
> "nick_name": "lensfrex", |
||||
> "desc": null, |
||||
> ... |
||||
> ] |
||||
> ``` |
||||
|
||||
*~~先这样吧~~* |
@ -0,0 +1,17 @@ |
||||
package me.lensfrex.trailblazer.api.v1; |
||||
|
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.boot.builder.SpringApplicationBuilder; |
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
||||
|
||||
@SpringBootApplication |
||||
public class ServerMain extends SpringBootServletInitializer { |
||||
@Override |
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { |
||||
return application.sources(ServerMain.class); |
||||
} |
||||
public static void main(String[] args) { |
||||
SpringApplication.run(ServerMain.class, args); |
||||
} |
||||
} |
@ -0,0 +1,70 @@ |
||||
package me.lensfrex.trailblazer.api.v1.beans; |
||||
|
||||
import com.google.gson.annotations.SerializedName; |
||||
|
||||
import java.util.Date; |
||||
|
||||
public class TokenBody { |
||||
@SerializedName("api_ver") |
||||
private String apiVersion; |
||||
|
||||
@SerializedName("user") |
||||
private String username; |
||||
|
||||
@SerializedName("uid") |
||||
private long uid; |
||||
|
||||
@SerializedName("uuid") |
||||
private String UUID; |
||||
|
||||
@SerializedName("exp") |
||||
private Date invalidDate; |
||||
|
||||
public TokenBody(String apiVersion, String username, long uid, String UUID, Date invalidDate) { |
||||
this.apiVersion = apiVersion; |
||||
this.username = username; |
||||
this.uid = uid; |
||||
this.UUID = UUID; |
||||
this.invalidDate = invalidDate; |
||||
} |
||||
|
||||
public String getApiVersion() { |
||||
return apiVersion; |
||||
} |
||||
|
||||
public void setApiVersion(String apiVersion) { |
||||
this.apiVersion = apiVersion; |
||||
} |
||||
|
||||
public String getUsername() { |
||||
return username; |
||||
} |
||||
|
||||
public void setUsername(String username) { |
||||
this.username = username; |
||||
} |
||||
|
||||
public long getUid() { |
||||
return uid; |
||||
} |
||||
|
||||
public void setUid(long uid) { |
||||
this.uid = uid; |
||||
} |
||||
|
||||
public String getUUID() { |
||||
return UUID; |
||||
} |
||||
|
||||
public void setUUID(String UUID) { |
||||
this.UUID = UUID; |
||||
} |
||||
|
||||
public Date getInvalidDate() { |
||||
return invalidDate; |
||||
} |
||||
|
||||
public void setInvalidDate(Date invalidDate) { |
||||
this.invalidDate = invalidDate; |
||||
} |
||||
} |
@ -0,0 +1,18 @@ |
||||
package me.lensfrex.trailblazer.api.v1.controllers; |
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
||||
/** |
||||
* 只是方便前端测试自己到底发了什么数据给后端 |
||||
* 返回数据不是很详细,只是把数据体原样给返回了 |
||||
* 但是header信息之类的并没有提供 |
||||
*/ |
||||
@RequestMapping("/test") |
||||
public class FeedBack { |
||||
@PostMapping() |
||||
public String returnPostRequest(String string) { |
||||
return string; |
||||
} |
||||
} |
@ -0,0 +1,15 @@ |
||||
package me.lensfrex.trailblazer.api.v1.controllers; |
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
@RestController |
||||
@RequestMapping("/") |
||||
public class Index { |
||||
@GetMapping() |
||||
public String index() { |
||||
return "Here is the API root of Trailblazer.</br>\n" + |
||||
"To use the API currently, please see the Trailblazer RESTFul API document."; |
||||
} |
||||
} |
@ -0,0 +1,49 @@ |
||||
package me.lensfrex.trailblazer.api.v1.controllers.auth.login; |
||||
|
||||
import com.google.gson.Gson; |
||||
import com.google.gson.JsonParseException; |
||||
import me.lensfrex.trailblazer.api.v1.beans.requests.LoginRequestBody; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseBase; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseCode; |
||||
import me.lensfrex.trailblazer.api.v1.exceptions.RequestDataInvalidException; |
||||
import me.lensfrex.trailblazer.api.v1.exceptions.user.LoginInfoWrongException; |
||||
import me.lensfrex.trailblazer.api.v1.service.auth.login.LoginService; |
||||
import me.lensfrex.trailblazer.api.v1.utils.InputChecker; |
||||
import org.mindrot.jbcrypt.BCrypt; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.annotation.Resource; |
||||
|
||||
@RestController |
||||
@RequestMapping("/user") |
||||
public class Login { |
||||
private static final Gson gson = new Gson(); |
||||
|
||||
@Resource |
||||
private LoginService loginService; |
||||
|
||||
@PostMapping(value = "/login", produces = "application/json") |
||||
public String login(@RequestBody String request) { |
||||
LoginRequestBody loginRequestBody; |
||||
try { |
||||
loginRequestBody = gson.fromJson(request, LoginRequestBody.class); |
||||
if (InputChecker.hasInvalidChar(loginRequestBody.getUserName()) || |
||||
InputChecker.hasInvisibleChar(loginRequestBody.getPassword())) { |
||||
throw new RequestDataInvalidException(); |
||||
} |
||||
|
||||
return gson.toJson(loginService.checkLogin(loginRequestBody)); |
||||
} catch (JsonParseException | RequestDataInvalidException e) { |
||||
return gson.toJson(ResponseBase.error(ResponseCode.REQUEST_FORMAT_INVALID, "请求的数据格式不对")); |
||||
} catch (LoginInfoWrongException e) { |
||||
return gson.toJson(ResponseBase.error(ResponseCode.PASSWORD_WRONG, "用户名或密码错误")); |
||||
} catch (Exception e) { |
||||
System.err.println(e.getMessage()); |
||||
return gson.toJson(ResponseBase.error(ResponseCode.SERVER_ERROR, "服务器内部错误,请联系那个背锅的家伙")); |
||||
} |
||||
} |
||||
|
||||
public boolean identifyPassword(String originPassword, String bcryptPassword) { |
||||
return BCrypt.checkpw(originPassword, bcryptPassword); |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
package me.lensfrex.trailblazer.api.v1.controllers.auth.register; |
||||
|
||||
import com.google.gson.Gson; |
||||
import com.google.gson.JsonParseException; |
||||
import me.lensfrex.trailblazer.api.v1.beans.requests.RegisterRequestBody; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseCode; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseBase; |
||||
import me.lensfrex.trailblazer.api.v1.exceptions.RequestDataInvalidException; |
||||
import me.lensfrex.trailblazer.api.v1.exceptions.user.UserNameAlreadyExistsException; |
||||
import me.lensfrex.trailblazer.api.v1.service.auth.register.RegisterService; |
||||
import me.lensfrex.trailblazer.api.v1.utils.InputChecker; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import javax.annotation.Resource; |
||||
|
||||
@RestController |
||||
@RequestMapping("/user") |
||||
public class Register { |
||||
@Resource |
||||
private RegisterService registerService; |
||||
|
||||
private static final Gson gson = new Gson(); |
||||
|
||||
@PostMapping(value = "/register", produces = "application/json") |
||||
public String register(@RequestBody String request) { |
||||
try { |
||||
RegisterRequestBody registerRequestBody = gson.fromJson(request, RegisterRequestBody.class); |
||||
|
||||
if (registerRequestBody == null || |
||||
InputChecker.hasInvalidChar(registerRequestBody.getUserName()) || |
||||
InputChecker.hasInvisibleChar(registerRequestBody.getPassword())) { |
||||
|
||||
throw new RequestDataInvalidException(); |
||||
} |
||||
|
||||
return gson.toJson(ResponseBase.success(registerService.register(registerRequestBody))); |
||||
} catch (JsonParseException | RequestDataInvalidException e) { |
||||
return gson.toJson(ResponseBase.error(ResponseCode.REQUEST_FORMAT_INVALID, "请求的数据不正确")); |
||||
} catch (UserNameAlreadyExistsException e) { |
||||
return gson.toJson(ResponseBase.error(ResponseCode.USER_ALREADY_EXISTS, "用户名已经被使用")); |
||||
} catch (Exception e) { |
||||
return gson.toJson(ResponseBase.error(ResponseCode.SERVER_ERROR, "服务器程序发生错误,有个家伙又写bug了。Error:" + e.getMessage())); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,16 @@ |
||||
package me.lensfrex.trailblazer.api.v1.controllers.auth.token; |
||||
|
||||
|
||||
import me.lensfrex.trailblazer.api.v1.utils.jwt.JWTManager; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
@RestController |
||||
@RequestMapping("/token") |
||||
public class TokenChecker { |
||||
public static final JWTManager jwtManager = JWTManager.getInstance(); |
||||
|
||||
@PostMapping(value = "/check", produces = "application/json") |
||||
public String checkTokenAvailable(@RequestBody String request) { |
||||
return String.valueOf(jwtManager.verifyToken(request)); |
||||
} |
||||
} |
@ -0,0 +1,16 @@ |
||||
package me.lensfrex.trailblazer.api.v1.controllers.auth.token; |
||||
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RequestMethod; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
@RestController |
||||
@RequestMapping("/token") |
||||
public class TokenRefresher { |
||||
@RequestMapping(value = "/refresh", method = RequestMethod.POST, produces = "application/json") |
||||
public String refreshToken(@RequestBody String request) { |
||||
return request; |
||||
} |
||||
} |
@ -0,0 +1,15 @@ |
||||
package me.lensfrex.trailblazer.api.v1.controllers.profile; |
||||
|
||||
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
||||
@RequestMapping("/profile") |
||||
public class Profile { |
||||
|
||||
// @Path("/getItems/{uid}")
|
||||
// @Produces(MediaType.APPLICATION_JSON)
|
||||
public String getProfiles(@RequestBody String uid) { |
||||
return "unfinished feature..."; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@ |
||||
package me.lensfrex.trailblazer.api.v1.exceptions.user; |
||||
|
||||
public class UserNameAlreadyExistsException extends Exception { |
||||
public UserNameAlreadyExistsException(String message) { |
||||
super(message); |
||||
} |
||||
|
||||
public UserNameAlreadyExistsException() { |
||||
super("用户名已经被使用"); |
||||
} |
||||
} |
@ -1,20 +0,0 @@ |
||||
package me.lensfrex.trailblazer.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,16 +0,0 @@ |
||||
package me.lensfrex.trailblazer.api.v1.service; |
||||
|
||||
import jakarta.ws.rs.GET; |
||||
import jakarta.ws.rs.Path; |
||||
import jakarta.ws.rs.Produces; |
||||
import jakarta.ws.rs.core.MediaType; |
||||
|
||||
@Path("/") |
||||
public class Index { |
||||
@GET |
||||
@Produces(MediaType.TEXT_HTML) |
||||
public String index() { |
||||
return "Here is the API root of Trailblazer.</br>\n" + |
||||
"To use the API currently, please see the Trailblazer RESTFul API document."; |
||||
} |
||||
} |
@ -0,0 +1,51 @@ |
||||
package me.lensfrex.trailblazer.api.v1.service.auth.login; |
||||
|
||||
import me.lensfrex.trailblazer.api.v1.beans.requests.LoginRequestBody; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.LoginResponseData; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseBase; |
||||
import me.lensfrex.trailblazer.api.v1.dao.UserDao; |
||||
import me.lensfrex.trailblazer.api.v1.exceptions.user.LoginInfoWrongException; |
||||
import me.lensfrex.trailblazer.api.v1.pojos.UserInformation; |
||||
import me.lensfrex.trailblazer.api.v1.utils.jwt.JWTManager; |
||||
import org.mindrot.jbcrypt.BCrypt; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import java.time.Instant; |
||||
import java.time.temporal.ChronoUnit; |
||||
import java.util.Date; |
||||
|
||||
@Service |
||||
public class LoginService { |
||||
private static final JWTManager jwtManager = JWTManager.getInstance(); |
||||
|
||||
public ResponseBase<LoginResponseData> checkLogin(LoginRequestBody loginRequestBody) throws LoginInfoWrongException { |
||||
UserInformation userDatabaseInformation = UserDao.getUser(loginRequestBody.getUserName()); |
||||
|
||||
if (userDatabaseInformation == null) { |
||||
throw new LoginInfoWrongException(); |
||||
} |
||||
|
||||
if (!identifyPassword(loginRequestBody.getPassword(), userDatabaseInformation.password)) { |
||||
throw new LoginInfoWrongException(); |
||||
} |
||||
|
||||
Date expireDate = Date.from(Instant.now().plus(JWTManager.TOKEN_DEFAULT_EXPIRE_DAY, ChronoUnit.DAYS)); |
||||
String userToken = jwtManager.createNewJWT(loginRequestBody.getUserName(), |
||||
userDatabaseInformation.uuid, |
||||
userDatabaseInformation.uid, |
||||
expireDate); |
||||
|
||||
LoginResponseData loginResponseData = new LoginResponseData( |
||||
userDatabaseInformation.uid, |
||||
userDatabaseInformation.uuid, |
||||
userDatabaseInformation.accountStatus, |
||||
userToken, |
||||
expireDate.getTime()); |
||||
|
||||
return ResponseBase.success(loginResponseData); |
||||
} |
||||
|
||||
private boolean identifyPassword(String originPassword, String bcryptPassword) { |
||||
return BCrypt.checkpw(originPassword, bcryptPassword); |
||||
} |
||||
} |
@ -0,0 +1,39 @@ |
||||
package me.lensfrex.trailblazer.api.v1.service.auth.register; |
||||
|
||||
import me.lensfrex.trailblazer.api.v1.beans.requests.RegisterRequestBody; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.RegisterResponseData; |
||||
import me.lensfrex.trailblazer.api.v1.dao.UserDao; |
||||
import me.lensfrex.trailblazer.api.v1.exceptions.user.UserNameAlreadyExistsException; |
||||
import me.lensfrex.trailblazer.api.v1.utils.jwt.JWTManager; |
||||
import org.mindrot.jbcrypt.BCrypt; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import java.time.Instant; |
||||
import java.time.temporal.ChronoUnit; |
||||
import java.util.Date; |
||||
import java.util.UUID; |
||||
|
||||
@Service |
||||
public class RegisterService { |
||||
private static final JWTManager jwtManager = JWTManager.getInstance(); |
||||
|
||||
public RegisterResponseData register(RegisterRequestBody registerRequestBody) throws UserNameAlreadyExistsException { |
||||
|
||||
if (UserDao.isUserAlreadyExist(registerRequestBody.getUserName())) { |
||||
throw new UserNameAlreadyExistsException("用户名已经被使用"); |
||||
} |
||||
|
||||
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)); |
||||
|
||||
return new RegisterResponseData( |
||||
newUid, |
||||
userUUID, |
||||
jwtManager.createNewJWT(registerRequestBody.getUserName(), userUUID, newUid, expireDate), |
||||
expireDate.getTime()); |
||||
} |
||||
} |
@ -1,18 +1,10 @@ |
||||
package me.lensfrex.trailblazer.api.v1.service.token; |
||||
package me.lensfrex.trailblazer.api.v1.service.auth.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.trailblazer.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,7 @@ |
||||
package me.lensfrex.trailblazer.api.v1.service.auth.token; |
||||
|
||||
public class TokenRefresher { |
||||
public String refreshToken(String request) { |
||||
return request; |
||||
} |
||||
} |
@ -1,78 +0,0 @@ |
||||
package me.lensfrex.trailblazer.api.v1.service.login; |
||||
|
||||
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.trailblazer.api.v1.beans.requests.LoginRequestBody; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.LoginResponseData; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ErrorResponse; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseBase; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseCode; |
||||
import me.lensfrex.trailblazer.api.v1.exceptions.user.LoginInfoWrongException; |
||||
import me.lensfrex.trailblazer.api.v1.pojos.UserInformation; |
||||
import me.lensfrex.trailblazer.api.v1.utils.InputChecker; |
||||
import me.lensfrex.trailblazer.api.v1.dao.UserDao; |
||||
import me.lensfrex.trailblazer.api.v1.utils.jwt.JWTManager; |
||||
import org.mindrot.jbcrypt.BCrypt; |
||||
|
||||
import java.time.Instant; |
||||
import java.time.temporal.ChronoUnit; |
||||
import java.util.Date; |
||||
|
||||
@Path("/login") |
||||
public class Login { |
||||
private static final Gson gson = new Gson(); |
||||
private static final JWTManager jwtManager = JWTManager.getInstance(); |
||||
|
||||
@POST |
||||
@Produces(MediaType.APPLICATION_JSON) |
||||
public String login(String request) { |
||||
LoginRequestBody loginRequestBody; |
||||
try { |
||||
loginRequestBody = gson.fromJson(request, LoginRequestBody.class); |
||||
if (InputChecker.hasInvalidChar(loginRequestBody.getUserName()) || |
||||
InputChecker.hasInvisibleChar(loginRequestBody.getPassword())) { |
||||
ErrorResponse errorResponse = new ErrorResponse(100, "请求的用户名或密码非法"); |
||||
|
||||
return gson.toJson(errorResponse); |
||||
} |
||||
|
||||
UserInformation userDatabaseInformation = UserDao.getUser(loginRequestBody.getUserName()); |
||||
|
||||
if (userDatabaseInformation == null) { |
||||
throw new LoginInfoWrongException(); |
||||
} |
||||
|
||||
if (!identifyPassword(loginRequestBody.getPassword(), userDatabaseInformation.password)) { |
||||
throw new LoginInfoWrongException(); |
||||
} |
||||
|
||||
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( |
||||
userDatabaseInformation.uid, |
||||
userDatabaseInformation.uuid, |
||||
userDatabaseInformation.accountStatus, |
||||
userToken, |
||||
expireDate.getTime()); |
||||
|
||||
ResponseBase<LoginResponseData> response = ResponseBase.success(loginResponseData); |
||||
|
||||
return gson.toJson(response); |
||||
} catch (JsonParseException e) { |
||||
return gson.toJson(ResponseBase.error(ResponseCode.REQUEST_FORMAT_INVALID, "请求的数据格式不对")); |
||||
} catch (LoginInfoWrongException e) { |
||||
return gson.toJson(ResponseBase.error(ResponseCode.PASSWORD_WRONG, "用户名或密码错误")); |
||||
} catch (Exception e) { |
||||
return gson.toJson(ResponseBase.error(ResponseCode.SERVER_ERROR, "服务器内部错误,请联系那个背锅的家伙")); |
||||
} |
||||
} |
||||
|
||||
public boolean identifyPassword(String originPassword, String bcryptPassword) { |
||||
return BCrypt.checkpw(originPassword, bcryptPassword); |
||||
} |
||||
} |
@ -1,19 +0,0 @@ |
||||
package me.lensfrex.trailblazer.api.v1.service.profile; |
||||
|
||||
import jakarta.ws.rs.GET; |
||||
import jakarta.ws.rs.Path; |
||||
import jakarta.ws.rs.PathParam; |
||||
import jakarta.ws.rs.Produces; |
||||
import jakarta.ws.rs.core.MediaType; |
||||
|
||||
@Path("/profile") |
||||
public class Profile { |
||||
|
||||
@GET |
||||
@Path("/getItems/{uid}") |
||||
@Produces(MediaType.APPLICATION_JSON) |
||||
public String getProfiles(@PathParam("uid") String uid) { |
||||
return "unfinished feature..."; |
||||
} |
||||
|
||||
} |
@ -1,67 +0,0 @@ |
||||
package me.lensfrex.trailblazer.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.trailblazer.api.v1.beans.requests.RegisterRequestBody; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseCode; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.RegisterResponseData; |
||||
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseBase; |
||||
import me.lensfrex.trailblazer.api.v1.dao.UserDao; |
||||
import me.lensfrex.trailblazer.api.v1.exceptions.RequestDataInvalidException; |
||||
import me.lensfrex.trailblazer.api.v1.utils.InputChecker; |
||||
import me.lensfrex.trailblazer.api.v1.utils.jwt.JWTManager; |
||||
import org.mindrot.jbcrypt.BCrypt; |
||||
|
||||
import java.time.Instant; |
||||
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())); |
||||
} |
||||
} |
||||
} |
@ -1,16 +0,0 @@ |
||||
package me.lensfrex.trailblazer.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; |
||||
} |
||||
} |
@ -0,0 +1,2 @@ |
||||
server: |
||||
port: 64888 |
Loading…
Reference in new issue