I am trying to implement Signup with Github
in a sample project, where front-end code is made up of ReactJS and Backend API is made up of Spring Boot.
I am not using Server Template Engines such as ThymeLeaf or Mustache, but only creating RESTful APIs.
Below is my Spring Security Configuration.
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final GithubOAuth2UserService githubOAuth2UserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/v1/health-check")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/")
.and()
.oauth2Login()
.userInfoEndpoint()
.userService(githubOAuth2UserService);
}
}
- Below is my code for
GithubOAuth2UserService
@RequiredArgsConstructor
@Service
public class GithubOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private final UserRepository userRepository;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
String registrationId = userRequest.getClientRegistration().getRegistrationId();
System.out.println(registrationId);
String userNameAttributeName = userRequest.getClientRegistration()
.getProviderDetails().getUserInfoEndpoint()
.getUserNameAttributeName();
System.out.println(userNameAttributeName);
OAuthAttributes attributes = OAuthAttributes.ofGithub(userNameAttributeName, oAuth2User.getAttributes());
User user = saveUser(attributes);
return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(user.getRole().name())),
attributes.getAttributes(),
attributes.getNameAttributeKey()
);
}
@Transactional
protected User saveUser(OAuthAttributes attributes) {
System.out.println("SAVE USER!");
if(userRepository.findByEmail(attributes.getEmail()).isPresent()) {
throw new UserEmailConflictException();
} else {
User user = attributes.toEntity();
return userRepository.save(user);
}
}
}
- Finally,
OAuthAttributes
is as below.
@Getter
public class OAuthAttributes {
private Map<String, Object> attributes;
private String nameAttributeKey;
private String name;
private String email;
@Builder
public OAuthAttributes(Map<String, Object> attributes, String nameAttributeKey, String name, String email) {
this.attributes = attributes;
this.nameAttributeKey = nameAttributeKey;
this.name = name;
this.email = email;
}
public static OAuthAttributes ofGithub(String userNameAttributeName, Map<String, Object> attributes) {
return OAuthAttributes.builder()
.name((String) attributes.get("name"))
.email((String) attributes.get("email"))
.attributes(attributes)
.nameAttributeKey(userNameAttributeName)
.build();
}
public User toEntity() {
return User.builder()
.name(name)
.email(email)
.build();
}
}
- Via PostMan, I can see the API result as below, but my ReactJS code doesn't show anything, and just refreshes the page.
- On ReactJS, it calls this API like below.
// OnClick function
const result = await axios.get("http://localhost:8080/oauth2/authorization/github");
console.log(result);
UPDATE
I am getting CORS policy violation, and I configured this using a configuration class below. Is this related to
SecurityConfig
class ?
@Configuration
@EnableWebMvc
public class CORSConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedMethods("*");
}
}
Thank you so much in advance. If any code needs to be shown, I will happily edit this post.