티스토리 뷰

1. Controller 생성

- AuthController

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/api/auth")
public class AuthController {
.....
  @PostMapping("/signin")
  public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {

      Authentication authentication = authenticationManager.authenticate(
      						new UsernamePasswordAuthenticationToken
     	 (loginRequest.getUsername(), loginRequest.getPassword()));

      SecurityContextHolder.getContext().setAuthentication(authentication);
      
      String jwt = jwtUtils.generateJwtToken(authentication);

      UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();	
      
      List<String> roles = userDetails.getAuthorities().stream()
              .map(item -> item.getAuthority())
              .collect(Collectors.toList());

      return ResponseEntity.ok(new JwtResponse
      	(jwt,userDetails.getId(), userDetails.getUsername(),userDetails.getEmail(),roles));}


}

- username, password 틀리면 AuthEntryPointJwt 호출하여 에러 메세지가 나온다.
- username, password 맞으면 JwtToken에서 토큰을 생성하고 반환 값으로 Id, username, email, roles를 반환한다.

 

@PostMapping("/signup")
	public ResponseEntity<?> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
		System.out.println("회원가입 시도");
		if (userRepository.existsByUsername(signUpRequest.getUsername())) {
			System.out.println(userRepository.existsByUsername(signUpRequest.getUsername()));
			return ResponseEntity
				.badRequest()
				.body(new MessageResponse("Error: Username is already taken!"));
		}

		if (userRepository.existsByEmail(signUpRequest.getEmail())) {
			return ResponseEntity
				.badRequest()
				.body(new MessageResponse("Error: Email is already in use!"));
		}
		// Create new user's account
		User user = new User(signUpRequest.getUsername(), 
							 signUpRequest.getEmail(),
							 encoder.encode(signUpRequest.getPassword()));
                             
		Set<String> strRoles = signUpRequest.getRole();
		Set<Role> roles = new HashSet<>();   

		if (strRoles == null) {
			Role userRole = roleRepository.findByName(ERole.ROLE_USER)
				.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
			roles.add(userRole);
		} 
		user.setRoles(roles);
		userRepository.save(user);
		System.out.println(userRepository.save(user));

		return ResponseEntity.ok(new MessageResponse("User registered successfully!"));
	}

- userRepository.existsByUsername(signUpRequest.getUsername( ) 입력된 username을 DB의 username 같은 값이 있다면 오류를 출력한다. email 마찬가지이다.

- 권한이 uesr, admin, moderator 3개이므로 회원가입할 때 user 권한을 주기 위해서 ERole.ROLE_USER 추가한다. 

- 동일한 값이 없다면 user에 담아줘서 userRepository.save(user)에 저장하고 return response 값을 react에게 넘겨준다.

 

- RoleController

@CrossOrigin(origins = "*", maxAge = 3600)  // 3600초 동안 preflight 결과를 캐쉬 저장
@RestController
@RequestMapping("/api/test")
public class TestController {
	@GetMapping("/all")
	public String allAccess() {
		return "메인 페이지";
	}
	
	@GetMapping("/user")
	@PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")
	public String userAccess() {
		return "유저 페이지";
	}

	@GetMapping("/mod")
	@PreAuthorize("hasRole('MODERATOR')")
	public String moderatorAccess() {
		return "중재자 페이지";
	}

	@GetMapping("/admin")
	@PreAuthorize("hasRole('ADMIN')")
	public String adminAccess() {
		return "관리자 페이지";
	}
}

- @PreAuthorize 어노테이션을 통해 권한 별로 통제 한다.