클라이언트에서 로그인 정보를 서버로 전송한 다음, 서버로부터 발급된 토큰을 받아 로컬 스토리지에 저장하는 코드이다.
리액트 + 스프링부트의 조합이다.
클라이언트
formData 형식으로 로그인 정보를 넘겨주었다. 이후 발급받은 토큰을 로컬 스토리지에 저장하고, 필요할때마다 로컬스토리지에서 가져오면 된다.
const response = await axios.post('http://localhost:8080/login', frm);
// 헤더에서 토큰 추출
let token = response.headers['authorization'];
// 토큰을 localStorage에 set
if(typeof token == "undefined" || token == null){
console.log('User Login Failed');
}else{
token = token.split(" ")[1];
localStorage.setItem("key", token);
const getToken = localStorage.getItem("key");
console.log('Token:', getToken);
console.log('User Login Success');
let payload = getToken.substring(getToken.indexOf('.')+1,getToken.lastIndexOf('.'));
let dec = JSON.parse(atob(payload));
setmessage(`${dec.username} 님 반갑습니다.`);
}
서버
public class LoginFilter extends UsernamePasswordAuthenticationFilter {
...
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
//클라이언트 요청에서 username, password 추출
String username = obtainUsername(request);
String password = obtainPassword(request);
//스프링 시큐리티에서 username과 password를 검증하기 위해서는 token에 담아야 함
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password, null);
//token에 담은 검증을 위한 AuthenticationManager로 전달
return authenticationManager.authenticate(authToken);
}
//로그인 성공시 실행하는 메소드 (여기서 JWT를 발급하면 됨)
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) {
//UserDetails
CustomUserDetails customUserDetails = (CustomUserDetails) authentication.getPrincipal();
String username = customUserDetails.getUsername();
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
Iterator<? extends GrantedAuthority> iterator = authorities.iterator();
GrantedAuthority auth = iterator.next();
String role = auth.getAuthority();
String token = jwtUtil.createJwt(username, role, 60 * 60 * 30L);
System.out.println("token: " + token);
response.addHeader("Access-Control-Expose-Headers", "Authorization");
response.addHeader("Authorization", "Bearer " + token);
}
...
}
서버로부터 받은 응답의 헤더에 토큰이 포함되어 있는 것을 볼 수 있다.
로컬 스토리지에 저장된 모습
로컬 스토리지에 저장된 토큰의 값을 파싱해서 유저의 정보를 추출할 수 있다.