Compare commits
No commits in common. 'spring-dev' and 'main' have entirely different histories.
spring-dev
...
main
@ -1,172 +0,0 @@ |
|||||||
# 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, |
|
||||||
> ... |
|
||||||
> ] |
|
||||||
> ``` |
|
||||||
|
|
||||||
*~~先这样吧~~* |
|
@ -1,17 +0,0 @@ |
|||||||
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); |
|
||||||
} |
|
||||||
} |
|
@ -1,70 +0,0 @@ |
|||||||
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; |
|
||||||
} |
|
||||||
} |
|
@ -1,18 +0,0 @@ |
|||||||
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; |
|
||||||
} |
|
||||||
} |
|
@ -1,15 +0,0 @@ |
|||||||
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."; |
|
||||||
} |
|
||||||
} |
|
@ -1,49 +0,0 @@ |
|||||||
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); |
|
||||||
} |
|
||||||
} |
|
@ -1,48 +0,0 @@ |
|||||||
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())); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,16 +0,0 @@ |
|||||||
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)); |
|
||||||
} |
|
||||||
} |
|
@ -1,16 +0,0 @@ |
|||||||
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; |
|
||||||
} |
|
||||||
} |
|
@ -1,15 +0,0 @@ |
|||||||
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..."; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,11 +0,0 @@ |
|||||||
package me.lensfrex.trailblazer.api.v1.exceptions.user; |
|
||||||
|
|
||||||
public class UserNameAlreadyExistsException extends Exception { |
|
||||||
public UserNameAlreadyExistsException(String message) { |
|
||||||
super(message); |
|
||||||
} |
|
||||||
|
|
||||||
public UserNameAlreadyExistsException() { |
|
||||||
super("用户名已经被使用"); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,20 @@ |
|||||||
|
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; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
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."; |
||||||
|
} |
||||||
|
} |
@ -1,51 +0,0 @@ |
|||||||
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); |
|
||||||
} |
|
||||||
} |
|
@ -1,39 +0,0 @@ |
|||||||
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,7 +0,0 @@ |
|||||||
package me.lensfrex.trailblazer.api.v1.service.auth.token; |
|
||||||
|
|
||||||
public class TokenRefresher { |
|
||||||
public String refreshToken(String request) { |
|
||||||
return request; |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,78 @@ |
|||||||
|
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); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
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..."; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,67 @@ |
|||||||
|
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,10 +1,18 @@ |
|||||||
package me.lensfrex.trailblazer.api.v1.service.auth.token; |
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; |
||||||
import me.lensfrex.trailblazer.api.v1.utils.jwt.JWTManager; |
import me.lensfrex.trailblazer.api.v1.utils.jwt.JWTManager; |
||||||
|
|
||||||
|
@Path("/token") |
||||||
public class TokenChecker { |
public class TokenChecker { |
||||||
public static final JWTManager jwtManager = JWTManager.getInstance(); |
public static final JWTManager jwtManager = JWTManager.getInstance(); |
||||||
|
|
||||||
|
@POST |
||||||
|
@Path("/check") |
||||||
|
@Produces(MediaType.APPLICATION_JSON) |
||||||
public String checkTokenAvailable(String request) { |
public String checkTokenAvailable(String request) { |
||||||
return String.valueOf(jwtManager.verifyToken(request)); |
return String.valueOf(jwtManager.verifyToken(request)); |
||||||
} |
} |
@ -0,0 +1,16 @@ |
|||||||
|
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; |
||||||
|
} |
||||||
|
} |
@ -1,2 +0,0 @@ |
|||||||
server: |
|
||||||
port: 64888 |
|
Loading…
Reference in new issue