game login 구현하기 [1] api 권한 추가
출처
Spring Boot and Spring Security with JWT including Access and Refresh Tokens 해당 유튜브 영상을 참고하여 진행했다!
💬왜 수정?
기존의 코드는 token만을 발급하며 권한에 대한 정보도 없이 반환하는 형식이였다. 토큰으로만 접속하는 방법을 사용하기엔 보안적인 문제가 있으므로 이왕 할때 제대로 하자는 마인드로 access_token과 refresh_token을 구별하여 제대로 해보자.
🔨Entity 수정
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Table(name = "game_users")
public class GameUserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@Column(name = "user_id", nullable = false, unique = true, length = 10)
private String userId;
@Column(nullable = false, length = 20)
private String name;
@Column(nullable = false, length = 150)
private String pw;
@ManyToMany(fetch = FetchType.EAGER)
private Collection<GameRole> roles = new ArrayList<>();
@CreationTimestamp
private LocalDateTime createdAt = LocalDateTime.now();
@Builder
public GameUserEntity(@NonNull String userId,@NonNull String name,@NonNull String pw) {
this.userId = userId;
this.name = name;
this.pw = pw;
}
}
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Table(name = "game_users")
public class GameUserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@Column(name = "user_id", nullable = false, unique = true, length = 10)
private String userId;
@Column(nullable = false, length = 20)
private String name;
@Column(nullable = false, length = 150)
private String pw;
@ManyToMany(fetch = FetchType.EAGER)
private Collection<GameRole> roles = new ArrayList<>();
@CreationTimestamp
private LocalDateTime createdAt = LocalDateTime.now();
@Builder
public GameUserEntity(@NonNull String userId,@NonNull String name,@NonNull String pw) {
this.userId = userId;
this.name = name;
this.pw = pw;
}
}
다음과 같이 권한 역할을 할 roles 를 추가하여주고 user 정보를 불러올때 함께 사용할 내용이므로 fetch 전략을 EAGER로 사용한다.
참고로 fetch 전략 EAGER는 아무데나 사용하면 나중에 피본다. 왜냐하면 User 테이블을 select 할때 무조건 GameRole 테이블을 함께 조회시키는 전략인데 이렇게 되면 나중에 쿼리의 속도가 엄청 느려지는 현상을 초래할 수 있다.
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class GameRole {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
GameRole의 코드
public interface GameRoleRepository extends CrudRepository<GameRole, Long> {
GameRole findByName(String name);
}
나중에 사용할 repository도 미리 구현
다음과 같이 잘 구현되었다.
그리고 GAME_ROLE 테이블에 ROLE_ADMIN을 미리 등록해주어야한다.
@Service
@RequiredArgsConstructor
@Transactional
@Slf4j
public class GameUserServiceImpl implements GameUserService{
private final BCryptPasswordEncoder passwordEncoder;
private final GameUserRepository gameUserRepository;
private final GameRoleRepository gameRoleRepository;
@Override
public ResponseGameUser join(RequestGameUser requestGameUser) {
log.info("user join {}", requestGameUser.getName());
//유효성 검사
GameUserEntity user = gameUserRepository.findByUserId(requestGameUser.getUserId());
if(user != null){
throw new JoinException(UserCode.EXIST_USER);
}
GameUserEntity gameUserEntity = GameUserEntity.builder()
.userId(requestGameUser.getUserId())
.pw(passwordEncoder.encode(requestGameUser.getPw()))
.name(requestGameUser.getName())
.build();
GameUserEntity save = gameUserRepository.save(gameUserEntity);
addRoleToUser(save.getUserId(), "ROLE_ADMIN");
ResponseGameUser responseGameUser = new ResponseGameUser(save.getUserId());
return responseGameUser;
}
@Override
public GameRole saveRole(GameRole role) {
log.info("user save role {}",role.getName());
return gameRoleRepository.save(role);
}
@Override
public void addRoleToUser(String userId, String roleName) {
log.info("user add user = {}, role = {}",userId, roleName);
GameUserEntity user = gameUserRepository.findByUserId(userId);
GameRole role = gameRoleRepository.findByName(roleName);
user.getRoles().add(role);
}
@Override
public GameUserVo getUserDetailByUserId(String userId) {
log.info("getUserDetailByUserId {}",userId);
GameUserEntity userEntity = gameUserRepository.findByUserId(userId);
GameUserVo gameUserVo = GameUserVo.builder()
.userId(userEntity.getUserId())
.name(userEntity.getName())
.pw(userEntity.getPw())
.createdAt(userEntity.getCreatedAt())
.build();
return gameUserVo;
}
@Override
public List<GameUserEntity> getAllUser() {
return Lists.newArrayList(gameUserRepository.findAll());
}
@Override
public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException {
GameUserEntity user = gameUserRepository.findByUserId(userId);
if(user == null) throw new UsernameNotFoundException("user가 존재하지 않습니다.");
return new User(user.getUserId(), user.getPw(), true, true, true, true, new ArrayList<>());
}
}
기존 로직에 addRoleToUser() 메서드를 추가하여 우선은 ROLE_ADMIN만 추가되도록 해놨다. 나중에는 회원가입시 모두 ROLE_ADMIN을 가지고 ROLE_MANAGER나 기타 권한을 추가하는 화면도 만들어서 관리하면 좋을거 같아서 service에 정의해서 사용했다.
그리고 회원가입을 진행하면
다음과 같이 1번 계정에 1번의 role이 추가되었다는 것을 확인할 수 있는데 회원가입을 하나 더 해보자
2번 계정에도 1번 권한이 추가되어진 것을 확인할 수 있었고
모든 user의 정보를 불러왔을 때 다음과 같이 roles의 정보가 추가되어 가져올 수 있다는 것을 확인할 수 있다.
Author And Source
이 문제에 관하여(game login 구현하기 [1] api 권한 추가), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ililil9482/game-login-구현하기-1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)