로그인

hyuko·2023년 5월 11일
0

팀 프로젝트

목록 보기
4/8

앞서 회원가입을 만들었다.

사용자 인증은 거의 모든 웹 애플리케이션에서 필수적인 부분입니다.
이 포스트에서는 Java와 Spring Boot를 사용하여 백엔드를,
React를 사용하여 프론트엔드를 구현하며 JWT(JSON Web Token)를 사용하여
사용자 인증을 처리하는 방법에 대해 살펴보겠습니다.


서버 사이드: Spring Boot

@ValidAspect
@PostMapping("/login")
public ResponseEntity<?> login(@Valid @RequestBody LoginReqDto loginReqDto, BindingResult bindingResult) {
    return ResponseEntity.ok(authService.signin(loginReqDto));
}

public JwtRespDto signin(LoginReqDto loginReqDto) {
	UsernamePasswordAuthenticationToken authenticationToken =
		new UsernamePasswordAuthenticationToken(loginReqDto.getEmail(), loginReqDto.getPassword());
	Authentication authentication = 
		authenticationManagerBuilder.getObject().authenticate(authenticationToken);

	return jwtTokenProvider.generateToken(authentication);
}

사용자 로그인 (signin):

로그인 요청은 "/login" 엔드포인트를 통해 처리됩니다.
클라이언트에서 로그인 요청이 오면 요청 본문에 포함된 LoginReqDto 객체를 이용해
이메일과 비밀번호로 이루어진 UsernamePasswordAuthenticationToken 객체를 생성합니다.
이 객체는 인증 매니저를 통해 인증이 진행되며, 인증 성공 시 JWT 토큰이 생성되어 반환됩니다.

@GetMapping("/authenticated")
public ResponseEntity<?> authenticated(@RequestHeader(value = "Authorization") String accessToken) {
    return ResponseEntity.ok(authService.authenticated(accessToken));
}

public boolean authenticated(String accessToken) {
	return jwtTokenProvider.validateToken(jwtTokenProvider.getToken(accessToken));
}

사용자 인증 (authenticated):

"/authenticated" 엔드포인트는
클라이언트가 전달한 토큰의 유효성을 확인하는 엔드포인트입니다.
사용자 인증 상태를 확인하기 위해 요청 헤더의 "Authorization" 필드에서 JWT 토큰을 추출하고,
해당 토큰의 유효성을 검증합니다.

@GetMapping("/principal")
public ResponseEntity<?> principal(String accessToken) {
    return ResponseEntity.ok(authService.getPrincipal(accessToken));
}

public PrincipalRespDto getPrincipal(String accessToken) {
	Claims claims = jwtTokenProvider.getClaims(jwtTokenProvider.getToken(accessToken));
	User userEntity = authRepository.findUserByEmail(claims.getSubject());
	...
	return PrincipalRespDto.builder()
			.userId(userEntity.getUserId())
			.email(userEntity.getEmail())
			.name(userEntity.getName())
			.phone(userEntity.getPhone())
			...
			.build();
}

주체 정보 가져오기 (getPrincipal):

"/principal" 엔드포인트는 현재 인증된 사용자의 주요 정보를 가져오는 엔드포인트입니다.
요청 헤더의 "Authorization" 필드에서 JWT 토큰을 추출하고,
해당 토큰의 주체(claims)를 이용하여 사용자 정보를 가져옵니다.


클라이언트 사이드: React

리액트에서는 사용자 로그인 상태를 관리하기 위해 Recoil이라는 상태 관리 라이브러리를 사용했습니다.

const signInUser = useMutation(async (loginData) => {
    try {
        const option = {
            headers: {
                'Content-Type': 'application/json'
            }
        }
        const response = await axios.post(`http://localhost:8080/api/v1/auth/login`, loginData, option);
        ...

        const accessToken = response.data.grantType + " " + response.data.accessToken;
        localStorage.setItem('accessToken', accessToken);
        setAuthState(true);
        navigate('/');
    }catch (error) {
        setErrorMessages({email: '', password: '', ...error.response.data.errorData});
    }
})

이벤트 핸들러 signInUser는 입력된 로그인 데이터를 서버에 전송하고
응답으로 받은 JWT 토큰을 로컬 스토리지에 저장합니다.

이처럼 서버 사이드와 클라이언트 사이드에서 JWT를 활용해 로그인과 인증을 구현할 수 있습니다.
이 방식을 사용하면 세션과 쿠키를 관리하는 번거로움 없이,
서버와 클라이언트 사이의 인증을 안전하게 처리할 수 있습니다.


다음으로...

우리의 메인 컨텐츠인 카카오맵 api 를 사용하여 화면에서 마커를 찍고
그 마커 정보를 서버에 넘겨 저장하는 기능에 대하여 알아보겠습니다.

profile
백엔드 개발자 준비중

0개의 댓글