reupload
This commit is contained in:
61
src/main/java/co/jp/app/common/ApiResponse.java
Normal file
61
src/main/java/co/jp/app/common/ApiResponse.java
Normal file
@ -0,0 +1,61 @@
|
||||
package co.jp.app.common;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ApiResponse<T> {
|
||||
private boolean success;
|
||||
private String message;
|
||||
private T data;
|
||||
|
||||
public static <T> ApiResponse<T> success(T data) {
|
||||
|
||||
return new ApiResponse<>(true, null, data);
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> fail(String message) {
|
||||
|
||||
return new ApiResponse<>(false, message, null);
|
||||
}
|
||||
|
||||
public ApiResponse() {
|
||||
}
|
||||
|
||||
public ApiResponse(boolean success, String message, T data) {
|
||||
this.success = success;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ApiResponse{" +
|
||||
"success=" + success +
|
||||
", message='" + message + '\'' +
|
||||
", data=" + data +
|
||||
'}';
|
||||
}
|
||||
}
|
18
src/main/java/co/jp/app/config/CorsConfig.java
Normal file
18
src/main/java/co/jp/app/config/CorsConfig.java
Normal file
@ -0,0 +1,18 @@
|
||||
package co.jp.app.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class CorsConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/api/**") // 允许 /api/ 下的所有请求
|
||||
.allowedOrigins("http://192.168.1.50:5173") // 允许来自该域的请求
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的 HTTP 方法
|
||||
.allowedHeaders("*") // 允许所有头部
|
||||
.allowCredentials(true); // 允许发送 Cookie
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package co.jp.app.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
63
src/main/java/co/jp/app/config/security/SecurityConfig.java
Normal file
63
src/main/java/co/jp/app/config/security/SecurityConfig.java
Normal file
@ -0,0 +1,63 @@
|
||||
package co.jp.app.config.security;
|
||||
|
||||
import co.jp.app.config.security.filter.JwtAuthenticationFilter;
|
||||
import co.jp.app.service.UserService;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfig {
|
||||
|
||||
private final JwtAuthenticationFilter jwtAuthenticationFilter;
|
||||
private final UserDetailsService userDetailsService;
|
||||
|
||||
public SecurityConfig(@Lazy JwtAuthenticationFilter jwtAuthenticationFilter, @Lazy UserDetailsService userDetailsService) {
|
||||
this.jwtAuthenticationFilter = jwtAuthenticationFilter;
|
||||
this.userDetailsService = userDetailsService;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationProvider authenticationProvider() {
|
||||
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
||||
authProvider.setUserDetailsService(userDetailsService);
|
||||
authProvider.setPasswordEncoder(passwordEncoder());
|
||||
return authProvider;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
|
||||
return authenticationConfiguration.getAuthenticationManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http.csrf(AbstractHttpConfigurer::disable)
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/api/user/login", "/api/user/register").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.authenticationProvider(authenticationProvider())
|
||||
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package co.jp.app.config.security.filter;
|
||||
|
||||
import co.jp.app.service.JwtService;
|
||||
import java.io.IOException;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
|
||||
@Component
|
||||
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
private final JwtService jwtService;
|
||||
private final UserDetailsService userDetailsService;
|
||||
|
||||
public JwtAuthenticationFilter(JwtService jwtService, UserDetailsService userDetailsService) {
|
||||
this.jwtService = jwtService;
|
||||
this.userDetailsService = userDetailsService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
|
||||
final String authHeader = request.getHeader("Authorization");
|
||||
final String jwt;
|
||||
final String username;
|
||||
|
||||
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
jwt = authHeader.substring(7);
|
||||
username = jwtService.extractUsername(jwt);
|
||||
|
||||
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
|
||||
if (jwtService.isTokenValid(jwt, userDetails)) {
|
||||
UsernamePasswordAuthenticationToken authToken =
|
||||
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
|
||||
|
||||
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(authToken);
|
||||
}
|
||||
}
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package co.jp.app.controller;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import co.jp.app.entity.ErrorEntity;
|
||||
import co.jp.app.entity.UserEntity;
|
||||
import co.jp.app.service.ErraService;
|
||||
import co.jp.app.service.UserService;
|
||||
|
||||
|
||||
@CrossOrigin("http://192.168.1.50:5173")
|
||||
@RestController("/api/login")
|
||||
public class LoginController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private ErraService erraService;
|
||||
|
||||
@GetMapping("/status")
|
||||
public String getStatusByNameOrEmail() {
|
||||
String input="aaa";
|
||||
|
||||
if (userByName == null && userByEmail == null) {
|
||||
return "全項目に入力してください";
|
||||
}
|
||||
|
||||
// 如果有找到,就固定使用 ID 1001 去查 erraEntity
|
||||
ErrorEntity erra = erraService.getStatusById(1001);
|
||||
|
||||
return erra.getStatus();
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import co.jp.app.service.PetService;
|
||||
|
||||
|
||||
@Controller
|
||||
|
||||
public class PetController {
|
||||
@ -19,7 +18,7 @@ public class PetController {
|
||||
|
||||
@GetMapping("/api/dogs/pet")
|
||||
public String getListByEntities(@RequestParam List<Integer> id) {
|
||||
service.getPetByID(id);
|
||||
service.getPetByID(id);
|
||||
return "pet";
|
||||
}
|
||||
}
|
||||
|
@ -9,20 +9,19 @@ import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import co.jp.app.entity.PetEntity;
|
||||
import co.jp.app.service.UploadService;
|
||||
|
||||
@CrossOrigin("http://192.168.1.50:5173")
|
||||
@Controller
|
||||
public class UploadController {
|
||||
|
||||
@Autowired
|
||||
private UploadService service;
|
||||
//private UploadService service;
|
||||
|
||||
@PostMapping("/api/dogs/upload")
|
||||
public String upload() {
|
||||
List<PetEntity> list = new ArrayList<PetEntity>();
|
||||
|
||||
service.saveAll(list);
|
||||
//service.saveAll(list);
|
||||
|
||||
return "upload";
|
||||
|
||||
|
77
src/main/java/co/jp/app/controller/UserController.java
Normal file
77
src/main/java/co/jp/app/controller/UserController.java
Normal file
@ -0,0 +1,77 @@
|
||||
package co.jp.app.controller;
|
||||
|
||||
import co.jp.app.common.ApiResponse;
|
||||
import co.jp.app.dto.LoginDto;
|
||||
import co.jp.app.dto.RegistrationDto;
|
||||
import co.jp.app.service.JwtService;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import co.jp.app.entity.ErrorEntity;
|
||||
import co.jp.app.entity.UserEntity;
|
||||
import co.jp.app.service.ErraService;
|
||||
import co.jp.app.service.UserService;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/user")
|
||||
public class UserController {
|
||||
|
||||
private final UserService userService;
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final JwtService jwtService;
|
||||
|
||||
public UserController(UserService userService, AuthenticationManager authenticationManager, JwtService jwtService) {
|
||||
this.userService = userService;
|
||||
this.authenticationManager = authenticationManager;
|
||||
this.jwtService = jwtService;
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
public ResponseEntity<?> registerUser(@Valid @RequestBody RegistrationDto registrationDto) {
|
||||
try {
|
||||
|
||||
UserEntity registeredUser = userService.registerNewUser(registrationDto);
|
||||
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(registeredUser.getEmail()));
|
||||
} catch (Exception e) {
|
||||
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.fail("ユーザー登録失敗しました。"));
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginDto loginDto) {
|
||||
try {
|
||||
Authentication authentication = authenticationManager.authenticate(
|
||||
new UsernamePasswordAuthenticationToken(loginDto.getEmail(), loginDto.getPassword())
|
||||
);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
|
||||
|
||||
String jwtToken = jwtService.generateToken(userDetails); // 生成单一的Token
|
||||
|
||||
Map<String, String> tokenResponse = new HashMap<>();
|
||||
tokenResponse.put("token", jwtToken);
|
||||
|
||||
return ResponseEntity.ok(ApiResponse.success(tokenResponse));
|
||||
|
||||
} catch (BadCredentialsException e) {
|
||||
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ApiResponse.fail("メールアドレスまたはパスワードが間違っています。"));
|
||||
} catch (Exception e) {
|
||||
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ApiResponse.fail("サーバーエラー。"));
|
||||
}
|
||||
}
|
||||
}
|
24
src/main/java/co/jp/app/dto/LoginDto.java
Normal file
24
src/main/java/co/jp/app/dto/LoginDto.java
Normal file
@ -0,0 +1,24 @@
|
||||
package co.jp.app.dto;
|
||||
|
||||
public class LoginDto {
|
||||
|
||||
private String email;
|
||||
|
||||
private String password;
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
34
src/main/java/co/jp/app/dto/RegistrationDto.java
Normal file
34
src/main/java/co/jp/app/dto/RegistrationDto.java
Normal file
@ -0,0 +1,34 @@
|
||||
package co.jp.app.dto;
|
||||
|
||||
public class RegistrationDto {
|
||||
|
||||
private String name;
|
||||
|
||||
private String email;
|
||||
|
||||
private String password;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
@ -5,10 +5,11 @@ import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "Pet")
|
||||
public class PetEntity{
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
public class PetEntity {
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
||||
@Id
|
||||
private int ID;
|
||||
@ -27,15 +28,15 @@ public class PetEntity{
|
||||
//犬の健康状態
|
||||
private String status;
|
||||
//犬の圖片
|
||||
private String image;
|
||||
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
private String image;
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
@ -92,6 +93,7 @@ public class PetEntity{
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public int getID() {
|
||||
return ID;
|
||||
}
|
||||
@ -99,5 +101,5 @@ public class PetEntity{
|
||||
public void setID(int iD) {
|
||||
ID = iD;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -7,9 +7,10 @@ import org.springframework.data.repository.query.Param;
|
||||
import co.jp.app.entity.ErrorEntity;
|
||||
|
||||
|
||||
public interface ErraRepository extends JpaRepository<ErrorEntity, Integer>{
|
||||
public interface ErrRepository extends JpaRepository<ErrorEntity, Integer>{
|
||||
|
||||
public default ErrorEntity getById(@Param("id") int id) {
|
||||
|
||||
return getById(id);
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package co.jp.app.repository;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
@ -9,10 +8,8 @@ import co.jp.app.entity.PetEntity;
|
||||
|
||||
public interface PetRepository extends JpaRepository<PetEntity, Integer> {
|
||||
|
||||
@Override
|
||||
default List<PetEntity> findAllById(Iterable<Integer> id) {
|
||||
return findAllById(id);
|
||||
@Override
|
||||
default List<PetEntity> findAllById(Iterable<Integer> id) {
|
||||
return findAllById(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,14 +4,14 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import co.jp.app.entity.ErrorEntity;
|
||||
import co.jp.app.repository.ErraRepository;
|
||||
import co.jp.app.repository.ErrRepository;
|
||||
|
||||
|
||||
@Service
|
||||
public class ErraService {
|
||||
|
||||
@Autowired
|
||||
ErraRepository erraRepository;
|
||||
ErrRepository erraRepository;
|
||||
|
||||
public ErrorEntity getStatusById(int id) {
|
||||
return erraRepository.getById(id);
|
||||
|
106
src/main/java/co/jp/app/service/JwtService.java
Normal file
106
src/main/java/co/jp/app/service/JwtService.java
Normal file
@ -0,0 +1,106 @@
|
||||
package co.jp.app.service;
|
||||
|
||||
import io.jsonwebtoken.*;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import io.jsonwebtoken.security.SignatureException;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.security.Key;
|
||||
import java.util.Base64;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class JwtService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JwtService.class);
|
||||
//log
|
||||
|
||||
@Value("${jwt.secret}")
|
||||
private String secretKey;
|
||||
|
||||
@Value("${jwt.token-expiration-ms}")
|
||||
private long tokenExpirationMs;
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
private Key getSignKey() {
|
||||
byte[] keyBytes = Base64.getDecoder().decode(secretKey);
|
||||
return Keys.hmacShaKeyFor(keyBytes);
|
||||
}
|
||||
|
||||
public String extractUsername(String token) {
|
||||
try {
|
||||
return extractClaim(token, Claims::getSubject);
|
||||
} catch (ExpiredJwtException e) {
|
||||
logger.warn("JWT token is expired when extracting username: {}", e.getMessage());
|
||||
return e.getClaims().getSubject();
|
||||
} catch (MalformedJwtException | SignatureException | UnsupportedJwtException | IllegalArgumentException e) {
|
||||
logger.error("Invalid JWT token when extracting username: {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T extractClaim(String token, @NotNull Function<Claims, T> claimsResolver) {
|
||||
final Claims claims = extractAllClaims(token);
|
||||
return claimsResolver.apply(claims);
|
||||
}
|
||||
|
||||
private Claims extractAllClaims(String token) {
|
||||
return Jwts
|
||||
.parserBuilder()
|
||||
.setSigningKey(getSignKey())
|
||||
.build()
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
}
|
||||
|
||||
public String generateToken(@NotNull UserDetails userDetails) {
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
return createToken(claims, userDetails.getUsername());
|
||||
}
|
||||
|
||||
private String createToken(Map<String, Object> claims, String subject) {
|
||||
return Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.setSubject(subject)
|
||||
.setIssuedAt(new Date(System.currentTimeMillis()))
|
||||
.setExpiration(new Date(System.currentTimeMillis() + tokenExpirationMs)) // 使用配置的过期时间
|
||||
.signWith(getSignKey(), SignatureAlgorithm.HS256)
|
||||
.compact();
|
||||
}
|
||||
|
||||
public boolean isTokenValid(String token, UserDetails userDetails) {
|
||||
try {
|
||||
final String username = extractUsername(token);
|
||||
if (username == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (username.equals(userDetails.getUsername()) && !isTokenActuallyExpired(token));
|
||||
} catch (ExpiredJwtException e) {
|
||||
|
||||
logger.warn("Token validation failed: Expired JWT - {}", e.getMessage());
|
||||
return false;
|
||||
} catch (MalformedJwtException | SignatureException | UnsupportedJwtException | IllegalArgumentException e) {
|
||||
|
||||
logger.error("Token validation failed: Invalid JWT (format, signature, etc.) - {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTokenActuallyExpired(String token) {
|
||||
return extractExpiration(token).before(new Date());
|
||||
}
|
||||
|
||||
private Date extractExpiration(String token) {
|
||||
return extractClaim(token, Claims::getExpiration);
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@ import org.springframework.stereotype.Service;
|
||||
import co.jp.app.entity.PetEntity;
|
||||
import co.jp.app.repository.PetRepository;
|
||||
|
||||
|
||||
@Service
|
||||
public class PetService {
|
||||
@Autowired
|
||||
@ -17,6 +16,6 @@ public class PetService {
|
||||
public List<PetEntity> getPetByID(Iterable<Integer> id) {
|
||||
|
||||
return dao.findAllById(id);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
package co.jp.app.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import co.jp.app.entity.PetEntity;
|
||||
import co.jp.app.repository.UploadRepository;
|
||||
|
||||
@Service
|
||||
public class UploadService {
|
||||
|
||||
@Autowired
|
||||
private UploadRepository uploadDao;
|
||||
|
||||
public List<PetEntity> saveAll(Iterable<PetEntity> entities) {
|
||||
|
||||
return uploadDao.saveAll(entities);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package co.jp.app.service;
|
||||
|
||||
<<<<<<< HEAD
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -8,10 +9,33 @@ import co.jp.app.entity.UserEntity;
|
||||
import co.jp.app.repository.userRepository;
|
||||
import jakarta.transaction.Transactional;
|
||||
|
||||
=======
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import co.jp.app.dto.RegistrationDto;
|
||||
import co.jp.app.entity.UserEntity;
|
||||
import co.jp.app.repository.UserRepository;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import co.jp.app.entity.PetEntity;
|
||||
import co.jp.app.repository.UploadRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
>>>>>>> 34de018ef0606dec4f6de48c8cc5c3f073a1fdc6
|
||||
|
||||
@Service
|
||||
public class UserService {
|
||||
public class UserService implements UserDetailsService {
|
||||
|
||||
<<<<<<< HEAD
|
||||
private final userRepository userEntityRepository;
|
||||
|
||||
@Autowired
|
||||
@ -20,35 +44,47 @@ public class UserService {
|
||||
this.userEntityRepository = userEntityRepository;
|
||||
this.passwordEncoder= passwordEncoder;
|
||||
|
||||
=======
|
||||
private final UserRepository userRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
|
||||
this.userRepository = userRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
>>>>>>> 34de018ef0606dec4f6de48c8cc5c3f073a1fdc6
|
||||
}
|
||||
|
||||
@Transactional // 整个注册过程应该是一个事务
|
||||
public UserEntity registerNewUser(String name, String email, String rawPassword) throws Exception {
|
||||
// 1. 检查邮箱是否已被注册
|
||||
if (userEntityRepository.existsByEmail(email)) {
|
||||
throw new Exception("错误:该邮箱地址已被注册!"); // 或者自定义异常
|
||||
@Transactional
|
||||
public UserEntity registerNewUser(@NotNull RegistrationDto registrationDto) throws Exception {
|
||||
|
||||
if (userRepository.existsByEmail(registrationDto.getEmail())) {
|
||||
throw new Exception("エラー:メール:" + registrationDto.getEmail() + " はすでに登録されました。");
|
||||
}
|
||||
|
||||
// (可选) 检查用户名是否已被注册 (如果您有用户名字段)
|
||||
// if (userEntityRepository.existsByUsername(username)) {
|
||||
// throw new Exception("错误:该用户名已被注册!");
|
||||
// }
|
||||
|
||||
// 2. 创建新的 UserEntity 对象
|
||||
UserEntity newUser = new UserEntity();
|
||||
newUser.setName(name);
|
||||
newUser.setEmail(email);
|
||||
newUser.setName(registrationDto.getName());
|
||||
newUser.setEmail(registrationDto.getEmail());
|
||||
newUser.setPassword(passwordEncoder.encode(registrationDto.getPassword()));
|
||||
|
||||
// 3. 对密码进行哈希加密 (非常重要!)
|
||||
// String hashedPassword = passwordEncoder.encode(rawPassword);
|
||||
// newUser.setPassword(hashedPassword);
|
||||
newUser.setPassword(rawPassword); // 实际项目中必须加密!这里为了简化先直接赋值
|
||||
return userRepository.save(newUser);
|
||||
}
|
||||
|
||||
// 4. 设置其他默认属性,例如账户状态、角色等 (如果需要)
|
||||
// newUser.setActive(true);
|
||||
// newUser.setRoles(...);
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
|
||||
UserEntity userEntity = userRepository.findByEmail(email)
|
||||
.orElseThrow(() -> new UsernameNotFoundException(email + " not found"));
|
||||
|
||||
// 5. 保存新用户到数据库
|
||||
return userEntityRepository.save(newUser);
|
||||
Collection<? extends GrantedAuthority> authorities = Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER")); // 示例:给所有用户一个ROLE_USER权限
|
||||
|
||||
return new User(
|
||||
userEntity.getEmail(),
|
||||
userEntity.getPassword(),
|
||||
true, // enabled
|
||||
true, // accountNonExpired
|
||||
true, // credentialsNonExpired
|
||||
true, // accountNonLocked
|
||||
authorities // 用户的权限集合
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user