更新
This commit is contained in:
@@ -16,6 +16,21 @@
|
||||
<artifactId>common-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
|
||||
@@ -9,7 +9,10 @@ public record CurrentUserResponse(
|
||||
String provinceCode,
|
||||
String areaCode,
|
||||
String tenantId,
|
||||
String tenantPath,
|
||||
String deptId,
|
||||
List<String> roles
|
||||
String deptPath,
|
||||
List<String> roles,
|
||||
String clientType
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -3,8 +3,11 @@ package com.k12study.api.auth.dto;
|
||||
public record LoginRequest(
|
||||
String username,
|
||||
String password,
|
||||
String mobile,
|
||||
String smsCode,
|
||||
String provinceCode,
|
||||
String areaCode,
|
||||
String tenantId
|
||||
String tenantId,
|
||||
String clientType
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.k12study.api.auth.remote;
|
||||
|
||||
/**
|
||||
* @description Auth 模块 HTTP 路径常量,供 Controller/Feign/网关白名单共用,避免字面量漂移
|
||||
* @filename AuthApiPaths.java
|
||||
* @author wangys
|
||||
* @copyright xyzh
|
||||
* @since 2026-04-17
|
||||
*/
|
||||
public final class AuthApiPaths {
|
||||
private AuthApiPaths() {
|
||||
}
|
||||
|
||||
public static final String BASE = "/auth";
|
||||
public static final String LOGIN = BASE + "/tokens";
|
||||
public static final String REFRESH = BASE + "/tokens/refresh";
|
||||
public static final String USERS_CURRENT = BASE + "/users/current";
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.k12study.api.auth.remote;
|
||||
|
||||
import com.k12study.api.auth.dto.CurrentUserResponse;
|
||||
import com.k12study.api.auth.dto.LoginRequest;
|
||||
import com.k12study.api.auth.dto.RefreshTokenRequest;
|
||||
import com.k12study.api.auth.dto.TokenResponse;
|
||||
import com.k12study.api.auth.remote.factory.RemoteAuthServiceFallbackFactory;
|
||||
import com.k12study.common.api.response.ApiResponse;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
|
||||
/**
|
||||
* @description Auth 远程服务契约;微服务模式按 Nacos 服务名寻址,单体/本地通过 k12study.remote.auth.url 直连兜底
|
||||
* @filename AuthRemoteApi.java
|
||||
* @author wangys
|
||||
* @copyright xyzh
|
||||
* @since 2026-04-17
|
||||
*/
|
||||
@FeignClient(
|
||||
contextId = "remoteAuthService",
|
||||
value = "${k12study.remote.auth.service-name:k12study-auth}",
|
||||
url = "${k12study.remote.auth.url:}",
|
||||
path = AuthApiPaths.BASE,
|
||||
fallbackFactory = RemoteAuthServiceFallbackFactory.class)
|
||||
public interface AuthRemoteApi {
|
||||
|
||||
/** 账号密码 / 手机号+验证码登录,成功返回 access+refresh 双令牌 */
|
||||
@PostMapping("/tokens")
|
||||
ApiResponse<TokenResponse> login(@RequestBody LoginRequest request);
|
||||
|
||||
/** 一次一换:撤销旧 refresh、签发新 access+refresh;失败返回 401 */
|
||||
@PostMapping("/tokens/refresh")
|
||||
ApiResponse<TokenResponse> refresh(@RequestBody RefreshTokenRequest request);
|
||||
|
||||
/** 解析 Authorization 中的 access token 返回当前用户画像(含 roleCodes/clientType) */
|
||||
@GetMapping("/users/current")
|
||||
ApiResponse<CurrentUserResponse> currentUser(
|
||||
@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authorization);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.k12study.api.auth.remote.factory;
|
||||
|
||||
import com.k12study.api.auth.dto.CurrentUserResponse;
|
||||
import com.k12study.api.auth.dto.LoginRequest;
|
||||
import com.k12study.api.auth.dto.RefreshTokenRequest;
|
||||
import com.k12study.api.auth.dto.TokenResponse;
|
||||
import com.k12study.api.auth.remote.AuthRemoteApi;
|
||||
import com.k12study.common.api.response.ApiResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @description Auth Feign 熔断降级工厂;下游不可达时返回 503 + message 说明,前端按统一响应体处理
|
||||
* @filename RemoteAuthServiceFallbackFactory.java
|
||||
* @author wangys
|
||||
* @copyright xyzh
|
||||
* @since 2026-04-17
|
||||
*/
|
||||
@Component
|
||||
public class RemoteAuthServiceFallbackFactory implements FallbackFactory<AuthRemoteApi> {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RemoteAuthServiceFallbackFactory.class);
|
||||
private static final int FALLBACK_CODE = 503;
|
||||
|
||||
@Override
|
||||
public AuthRemoteApi create(Throwable cause) {
|
||||
String reason = cause == null ? "unknown" : cause.getClass().getSimpleName() + ":" + cause.getMessage();
|
||||
log.warn("[auth-fallback] remote auth service degraded, cause={}", reason);
|
||||
String message = "auth 服务暂不可用,已触发降级:" + reason;
|
||||
return new AuthRemoteApi() {
|
||||
@Override
|
||||
public ApiResponse<TokenResponse> login(LoginRequest request) {
|
||||
return ApiResponse.failure(FALLBACK_CODE, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse<TokenResponse> refresh(RefreshTokenRequest request) {
|
||||
return ApiResponse.failure(FALLBACK_CODE, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse<CurrentUserResponse> currentUser(String authorization) {
|
||||
return ApiResponse.failure(FALLBACK_CODE, message);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user