Установка только HTTP-куки JWT из бэкэнда: Spring Boot и React JSJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Установка только HTTP-куки JWT из бэкэнда: Spring Boot и React JS

Сообщение Anonymous »

Я работаю над полнофункциональным проектом, используя Spring Boot и React JS. В целях безопасности я использую Токен доступа JWT с файлом cookie только HTTP.

Токен генерируется и устанавливается во время входа в систему. р>

Код: Выделить всё

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

@Component
public class CookieUtil {

public static void create(HttpServletResponse httpServletResponse, String name, String value, Boolean secure, Integer maxAge, String domain) {
Cookie cookie = new Cookie(name, value);
cookie.setSecure(secure);
cookie.setHttpOnly(true);
cookie.setMaxAge(maxAge);
cookie.setDomain(domain);
httpServletResponse.addCookie(cookie);
}

public static void clear(HttpServletResponse httpServletResponse, String name) {
Cookie cookie = new Cookie(name, null);
cookie.setMaxAge(1);
cookie.setPath("/");
cookie.setHttpOnly(true);
cookie.setDomain("localhost");
httpServletResponse.addCookie(cookie);

}
}
Теперь при тестировании с помощью клиента Postman я могу успешно установить файлы cookie —
Изображение

Но при использовании интерфейса React JS приложение, файл cookie не устанавливается.

Код: Выделить всё

import { useState } from 'react';
import './Login.css'
import axios from "axios";
import { apiPrefixV1, baseUrl } from '../../constants/AppConstants';
import { login as authLogin } from '../../redux/slices/authSlice';
import { useDispatch } from 'react-redux';
import { useNavigate } from 'react-router-dom';
const Login = () => {
const navigate = useNavigate()
const dispatch = useDispatch()
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [error, setError]=useState('')

const handleUsernameChange = (event) => {
setUsername(event.target.value);
};

const handlePasswordChange = (event) => {
setPassword(event.target.value);
};

const login = async (event) => {
event.preventDefault();

console.log('Email:', username);
console.log('Password:', password);

try{
const response=await axios.post(
`${baseUrl}/${apiPrefixV1}/consumer/login`,{
"username": username,
"password": password
}
)

console.log(response)

if(response.data['code']===2000){
const userData=response.data['data'];
if(userData) dispatch(authLogin({userData}));
navigate('/')
}
else{
setError(response.data['message'])
}
}
catch(err){
setError(err.message)
}
}

return (


CACMP Admin Login

Login using your department credentials

Login



Login



)

}

export default Login;
Я могу это обнаружить, поскольку в моем фильтре аутентификации-
требуемый файл cookie имеет значение null.

Код: Выделить всё

package com.ayushsingh.cacmp_backend.config.security;

import com.ayushsingh.cacmp_backend.config.security.service.ConsumerDetailsService;
import com.ayushsingh.cacmp_backend.config.security.service.CustomUserDetailsService;
import com.ayushsingh.cacmp_backend.config.security.service.DepartmentDetailsService;
import com.ayushsingh.cacmp_backend.config.security.util.JwtUtil;
import com.ayushsingh.cacmp_backend.constants.AppConstants;
import com.ayushsingh.cacmp_backend.models.dtos.authDtos.LoginRequestDto;
import com.ayushsingh.cacmp_backend.util.exceptionUtil.ApiException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.util.WebUtils;

import java.io.IOException;
import java.util.Arrays;

import static com.ayushsingh.cacmp_backend.constants.AppConstants.AUTH_HEADER;
import static com.ayushsingh.cacmp_backend.constants.AppConstants.PUBLIC_URLS;

public class CustomAuthFilter extends OncePerRequestFilter {

private final AuthenticationManager authenticationManager;
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver exceptionResolver;
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Autowired
private DepartmentDetailsService departmentDetailsService;
@Autowired
private ConsumerDetailsService consumerDetailsService;

@Value("${jwt.accessTokenCookieName}")
private String accessTokenCookieName;

public CustomAuthFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String uri = request.getRequestURI();  //-get the uri
//-if the uri is a login uri, then login
if (uri.endsWith(AppConstants.SIGN_IN_URI_ENDING)) {
//-obtain username and password
LoginRequestDto jwtAuthRequest = new ObjectMapper().readValue(request.getInputStream(), LoginRequestDto.class);
String username = jwtAuthRequest.getUsername();
String password = jwtAuthRequest.getPassword();
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
Authentication authenticationResult = null;
try {
authenticationResult = this.authenticationManager.authenticate(authenticationToken);

} catch (AuthenticationException e) {

SecurityContextHolder.getContext().setAuthentication(UsernamePasswordAuthenticationToken.unauthenticated(username, password));
exceptionResolver.resolveException(request, response, null, e);
}
if (authenticationResult != null) {
SecurityContextHolder.getContext().setAuthentication(authenticationResult);
}

filterChain.doFilter(request, response);
}
//-if not a login uri, check for access token
else {
String headerToken = this.getTokenFromCookie(request); //-obtain token from cookie
if (headerToken == null) {
headerToken = request.getHeader(AUTH_HEADER); //-if no token, obtain token from header
}
System.out.println("Header token: " + headerToken);
//-if still not found, return
if (headerToken == null) {
System.out.println("Token is not present");
//-match uri with public urls
try{
boolean isPublicUrl = Arrays.stream(PUBLIC_URLS).anyMatch(uri::endsWith);
if(isPublicUrl) {
filterChain.doFilter(request, response);
return;
}
else{
throw new ApiException("Access token is not present");
}
}
catch (ApiException e){
exceptionResolver.resolveException(request, response, null, e);
return;
}
}
UserDetails userDetails = null;
try {
headerToken = StringUtils.delete(headerToken, AppConstants.BEARER_TOKEN_PREFIX).trim();
String entityType = JwtUtil.extractEntityType(headerToken);
String username = JwtUtil.extractUsername(headerToken);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
if (entityType.equals(AppConstants.ENTITY_TYPE_CONSUMER)) {
userDetails = this.consumerDetailsService.loadUserByUsername(username);
} else if (entityType.equals(AppConstants.ENTITY_TYPE_USER)) {
userDetails = this.customUserDetailsService.loadUserByUsername(username);
} else if (entityType.equals(AppConstants.ENTITY_TYPE_DEPARTMENT)) {
userDetails = this.departmentDetailsService.loadUserByUsername(username);
}
if (userDetails == null) {
throw new ApiException("User not found with username: "  + username);
} else if (JwtUtil.validateToken(headerToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
filterChain.doFilter(request, response);
} else {
throw new ApiException("Token validation returned false");
}
} else {
throw new ApiException("Username not found in token");
}
} catch (ExpiredJwtException e) {
SecurityContextHolder.getContext().setAuthentication(UsernamePasswordAuthenticationToken.unauthenticated(userDetails, null));
exceptionResolver.resolveException(request, response, null, e);
} catch (UnsupportedJwtException | MalformedJwtException | SignatureException | IllegalArgumentException |
ApiException e) {
SecurityContextHolder.getContext().setAuthentication(UsernamePasswordAuthenticationToken.unauthenticated(userDetails, null));
exceptionResolver.resolveException(request, response, null, new ApiException(e.getMessage()));
}
}
}

private String getTokenFromCookie(HttpServletRequest httpServletRequest) {
Cookie cookie = WebUtils.getCookie(httpServletRequest, accessTokenCookieName);
return cookie != null ? cookie.getValue() : null;
}
}

Здесь файл cookie в методе getTokenFromCookie оказался нулевым!
Пожалуйста, помогите мне решить эту проблему. ! Я немного новичок в интерфейсе, поэтому не уверен, все ли правильно.

Подробнее здесь: https://stackoverflow.com/questions/780 ... d-react-js
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Отображение имени пользователя из токена JWT в заголовке React с помощью бэкэнда C#
    Anonymous » » в форуме C#
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Отображение имени пользователя из токена JWT в заголовке React с помощью бэкэнда C#
    Anonymous » » в форуме C#
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Чистые куки с RestTemplate перед тем, как сделать HTTP-звонок
    Anonymous » » в форуме JAVA
    0 Ответы
    3 Просмотры
    Последнее сообщение Anonymous
  • Лучше игнорировать проверку JWT (фильтр JWT) для некоторых конкретных маршрутов (вход в систему, регистр) в Spring Boot
    Anonymous » » в форуме JAVA
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • Spring boot websocket + реакция -> не получать сообщения от бэкэнда
    Anonymous » » в форуме JAVA
    0 Ответы
    21 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»