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; |
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,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