我正在使用React和Spring开发一个Web应用程序,我需要帮助使用Google通过OAuth2.0设置授权。在我的React代码中,我使用@react-oauth/google library,成功授权后,我从Google获取用户凭据。
现在我使用的是通过电子邮件+密码授权,但现在我想添加通过OAuth2授权的功能。
问题:
1.在前端从Google获取数据后,我应该怎么做?
1.我需要在Spring应用程序中更改什么以及如何更改才能允许通过OAuth2.0进行授权?
在React中的代码中从Google检索数据:
import { GoogleLogin } from '@react-oauth/google';
import { jwtDecode } from 'jwt-decode';
import React from 'react';
const OAuthButtons = () => {
const handleSuccess = (credentialResponse) => {
const decodedToken = jwtDecode(credentialResponse.credential);
};
return (
<div>
<GoogleLogin
onSuccess={handleSuccess}
onError={() => {
console.log('Login Failed');
}}
useOneTap
/>
</div>
);
};
export default OAuthButtons;
字符串
Spring中我的restController用于用户授权:
@RestController
@RequestMapping("/api/v1/auth")
public class AuthenticationRestController {
private final UserFacade userFacade;
private final AuthenticationManager authenticationManager;
private final JwtTokenProvider jwtTokenProvider;
public AuthenticationRestController(UserFacade userFacade, AuthenticationManager authenticationManager, JwtTokenProvider jwtTokenProvider) {
this.userFacade = userFacade;
this.authenticationManager = authenticationManager;
this.jwtTokenProvider = jwtTokenProvider;
}
@PostMapping("/registration")
public ResponseEntity<?> registration(@RequestBody UserRequestDto userRequestDto) {
try {
UserResponseDto user = userFacade.createUser(userRequestDto);
if (user != null) {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getId(), userRequestDto.getPassword()));
String token = jwtTokenProvider.createToken(user.getId(), user.getRole());
return ResponseEntity.ok(new UserWithJwtResponseDto(token, user));
} else {
throw new EntityExistException("");
}
} catch (EntityExistException e) {
return ResponseEntity.status(HttpStatus.CONFLICT).body(e.getMessage());
}
}
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody UserRequestDto req) {
try {
UserResponseDto user = userFacade.findUserByEmail(req.getEmail());
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getId(), req.getPassword()));
String token = jwtTokenProvider.createToken(user.getId(), user.getRole());
return ResponseEntity.ok(new UserWithJwtResponseDto(token, user));
} catch (AuthenticationException e) {
throw new BadCredentialsException("Invalid username or password");
}
}
}
型
我在服务器上的SecurityConfig:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final JwtTokenProvider jwtTokenProvider;
private static final String ADMIN_ENDPOINT = "/api/v1/admin/**";
private static final String LOGIN_ENDPOINT = "/api/v1/auth/**";
private static final String USER_ENDPOINT = "/api/v1/user/**";
private static final String TEACHER_REGISTRATION_ENDPOINT = "/api/v1/teacher/registrationTeacher";
private static final String TEACHER_ENDPOINT = "/api/v1/teacher/**";
private static final String COURSES_FOR_NOT_AUTH_ENDPOINT = "/api/v1/course/findAll";
private static final String ERROR = "/error";
@Autowired
public SecurityConfig(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors().and()
.exceptionHandling()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(LOGIN_ENDPOINT).permitAll()
.antMatchers(ERROR).permitAll()
.antMatchers(COURSES_FOR_NOT_AUTH_ENDPOINT).permitAll()
.antMatchers(ADMIN_ENDPOINT).hasRole(" developers:write")
.antMatchers(USER_ENDPOINT).hasRole("developers:read")
.antMatchers(TEACHER_REGISTRATION_ENDPOINT).hasRole("developers:read")
.antMatchers(TEACHER_ENDPOINT).hasRole("developers:educate")
.anyRequest().authenticated()
.and()
.apply(new JwtConfigurer(jwtTokenProvider))
.and()
.httpBasic();;
}
}
型
我的UserDetails安装:
@Service
public class JwtUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
public JwtUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findById(username).orElse(null);
if (user == null) {
throw new UsernameNotFoundException("User with username: " + username + " not found");
}
JwtUser jwtUser = InnerConverter.convertUserToJwtUser(user);
if (!jwtUser.isEnabled()) {
throw new DisabledException("User account is disabled");
}
return jwtUser;
}
}
型
1条答案
按热度按时间0lvr5msh1#
我有个坏消息
@react-oauth/google
使您的JavaScript前端成为OAuth2“公共”客户端,现在不鼓励这样做。您应该只使用OAuth2“机密”客户端,它们运行在您信任的服务器上从那里去哪里:
spring_authorization_server
框架“自己动手”(可能不是一个好主意,除非您对OAuth2和OpenID标准有深入的了解)spring-cloud-gateway
可以轻松地使用oauth2Login()
(使用spring-boot-starter-oauth2-client
)和TokenRelay
筛选器进行配置。我写了a tutorial for using
spring-cloud-gateway
as BFF。它是为Angular写的,但将其移植到React是微不足道的。