Это фрагмент сервиса:
Код: Выделить всё
@Override
@Transactional
public void setDefaultTheme(Long userId, String theme) {
UserPreferences userPreferences = getUserPreferencesOrCreate(userId);
userPreferences.setDefaultTheme(theme);
userPreferencesRepository.save(userPreferences);
}
Код: Выделить всё
@PostMapping("/set-default-theme")
public ResponseEntity setDefaultTheme(@Valid @RequestParam Long userId, @RequestParam String theme) {
userPreferencesService.setDefaultTheme(userId, theme);
return ResponseEntity
.status(HttpStatus.OK)
.body(new ResponseDto(HttpStatus.OK.toString(), getMessage(UserPreferencesConstants.DEFAULT_THEME_SET)));
}
Код: Выделить всё
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http, EmailAuthorizationManager emailAuthorizationManager, JwtConfigurer jwtConfigurer) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("api/csrf-token","/api/sign-in", "/api/sign-up", "/api/sign-out", "/api/create").permitAll()
.requestMatchers("/api/**").access(emailAuthorizationManager)
.anyRequest().authenticated())
.oauth2Login(oauth2 -> oauth2
.successHandler(oAuth2LoginSuccessHandler))
.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.decoder(jwtConfigurer.jwtDecoder())
.jwtAuthenticationConverter(jwtConfigurer.jwtAuthenticationConverter())))
.formLogin(form -> form
.loginPage("/oauth2/authorization/google"))
.logout(logout -> logout
.deleteCookies("JSESSIONID")
.clearAuthentication(true)
.invalidateHttpSession(true))
.build();
}
Код: Выделить всё
@Component
public class EmailAuthorizationManager implements AuthorizationManager {
@Override
public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext context) {
Authentication auth = authentication.get();
if (auth != null) {
String requestEmail = context.getRequest().getParameter("email");
boolean isAdmin = auth.getAuthorities().stream()
.anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals("ROLE_ADMIN"));
if (auth.getPrincipal() instanceof Jwt jwt) {
String jwtEmail = jwt.getClaimAsString("sub");
return new AuthorizationDecision(isAdmin || (jwtEmail != null && jwtEmail.equals(requestEmail)));
} else if (auth instanceof OAuth2AuthenticationToken) {
String oauth2Email = ((OAuth2AuthenticationToken) auth).getPrincipal().getAttribute("email");
return new AuthorizationDecision(isAdmin || (oauth2Email != null && oauth2Email.equals(requestEmail)));
}
}
return new AuthorizationDecision(false);
}
}
Код: Выделить всё
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(@NonNull CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(frontendUrl)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
}
};
}
Код: Выделить всё
import axios from "axios";
export const BASE_URL = 'http://localhost:8080/api';
let csrfToken: string | null = null;
export const setCsrfToken = (token: string) => {
csrfToken = token;
};
export const apiConfig = {
getHeaders: (language: string, token?: string) => {
return {
'Accept-Language': language,
'Authorization': token ? `Bearer ${token}` : '',
'Content-Type': 'application/json',
'X-CSRF-TOKEN': csrfToken || ''
};
}
};
export const getCsrfToken = async () => {
try {
const response = await axios.get(`${BASE_URL}/csrf-token`);
return response.data.token;
} catch (error) {
if (axios.isAxiosError(error) && error.response) {
throw new Error(error.response.data.errorMessage);
}
throw new Error('Unknown error');
}
};
axios.defaults.withCredentials = true;
Код: Выделить всё
export const setDefaultTheme = async (userId: number, theme: string, email: string, language: string, token: string) => {
const headers = apiConfig.getHeaders(language, token);
try {
const response = await axios.post(
`${BASE_URL}/set-default-theme?userId=${userId}&theme=${theme}&email=${email}`,
{},
{headers}
);
return response.data;
} catch (error) {
if (isAxiosError(error) && error.response) {
throw new Error(error.response.data.errorMessage);
}
throw new Error('Unknown error');
}
}
Код: Выделить всё
const {language} = useLanguage();
const {theme} = useTheme();
const {token, email} = useAuth();
const handleSaveButton = async () => {
try {
const decoded: any = jwtDecode(token);
const userId = decoded.userId;
await setDefaultTheme(userId, theme, email, language, token);
} catch (error) {
if (error instanceof Error) {
console.error(error);
}
}
}
Код: Выделить всё
{{BASE_URL}}/set-default-theme?userId=1&theme=light&[email protected]
Консоль возвращает:
Код: Выделить всё
Access to XMLHttpRequest at 'http://localhost:8080/api/set-default-theme?userId=1&theme=light&[email protected]' from origin 'http://localhost:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
DefaultTheme.tsx:21 Error: Unknown error
at setDefaultTheme (userPreferencesService.ts:33:15)
at async handleSaveButton (DefaultTheme.tsx:18:13)
POST http://localhost:8080/api/set-default-theme?userId=1&theme=light&[email protected] net::ERR_FAILED
Подробнее здесь: https://stackoverflow.com/questions/790 ... ut-200-whe