atrix
5월 23, 2024, 1:36오후
1
안녕하세요! localhost 환경에서 스프링부트, 리액트를 이용해 웹 게시판을 제작 중이며 OAuth2 로그인을 통해 JWT(Access, Refresh)발급하려고 합니다!
리액트에서는 하이퍼링크를 통해 로그인 요청을 스프링으로 하면 스프링에서 모든 OAuth2처리 후 OAuth2 서버로 부터 코드를 백엔드(스프링)으로 리다이렉트 받으면 스프링에서 Access, Refresh 토큰을 생성할려고 합니다.
첫번째 문제는 스프링에서 생성한 JWT를 리액트로 넘기려고 하는데 Access는 헤더, Refresh는 쿠키를 통해 넘기려고 했는데, Access를 스프링에서 리액트로 헤더로 넘기면 CORS가 발생합니다…
그래서 URL로 Access를 넘겨 리액트에서 파라미터를 통해 받고자 하는데 잘 못된 전달 방식일까요?
두번째 문제는 쿠키로 리액트에 전달한 Refresh토큰을 다시 스프링으로 넘길때(Access재발급을 위해) 쿠키값이 넘어오지 않는 문제가 발생했는데, localhost환경이 문제가 될까요?
감사합니다!
안녕하세요.
CORS는 구현하신 프론트서버(react)와 백앤드(Spring) 간 도메인이 다르기에 브라우저에서 발생시키는 것으로 백엔드측 Access-Control-Allow-Origin 설정을 통해 해결하실수 있습니다.
문의 주신 내용을 보면 카카오에서 획득한 access/refresh token을 프론트(브라우저)로 전달하고자 하는 것으로 이해 되는데요
일반적으로 jwt에 이러한 민감 정보를 담아 프론트로 전달하지 않습니다.
사용자의 접근토큰은 백앤드에서만 취급하는 것을 권장 드립니다.
atrix
5월 24, 2024, 5:16오전
4
답변 감사합니다!
제가 말한 토큰들은 로그인이 완료된 이후 백엔드에서 생성한 토큰입니다!
혹시 제가 로직을 잘 못 이해하고 있는걸까요…?
백엔드에서 생성한 토큰을 사용자가 사용하려면 프론트로 전달해줘야 이후에 권한이 필요한 api 이용시 다시 백엔드 전달해 인가를 받는다고 생각했습니다!
atrix
5월 24, 2024, 5:22오전
6
앗 아닙니다! 웹 게시판을 제작중이라 회원만 CRUD 작업을 할 수 있는 api 입니다!
카카오에서 전달하는 토큰이 아닌 서비스측 인가용 JWT를 말씀하신 경우라면
일반적으로 쿠키로 전달하여 처리합니다.
atrix
5월 24, 2024, 5:45오전
8
답변 감사합니다! 백엔드에서 생성한 토큰을 프론트로 넘길 때 access는 URL, refresh는 쿠키로 전달하려고 했습니다!
이후 서비스 이용 시 프론트에서 백엔드로 access를 헤더로 전달하려고 했습니다!
쿠키로 전달해야 한다는 말씀은 access, refresh 둘 다 일까요?
잘 이해하지 못하였는데요
access, refresh 는 어떤 값인가요?
atrix
5월 24, 2024, 6:10오전
10
제가 설명이 부족했나봅니다…
OAuth2 로그인이 완료되면 백엔드에서 생성하는 토큰입니다. access는 서비스측 인가용이고 refresh는 access 재발급을 위한 토큰입니다!
카카오에서 전달받은 토큰이 아닌 JWT 관리를 위한 토큰이라는 말씀인가요?
atrix
5월 24, 2024, 6:22오전
12
카카오에서 전달 받은 토큰을 이용해 유저정보는 DB에 저장한 이후 백엔드에서 생성한 토큰(유저 정보가 담긴 서비스측 인가용)입니다!
OAuth2에서 발급해준 토큰은 유저정보를 가져오는데에 이용 후 끝이라고 알고 있었습니다만 제가 잘 못 알고 있는걸까요…?
JWT을 사용하시는데 왜 access token과 refresh token을 별도 생성하여 관리하시나요?
atrix
5월 24, 2024, 7:02오전
14
woody.ho:
JWT을 사용하시는데
말씀하신 JWT는 카카오에서 발급해준 토큰을 말씀하시는걸까요…??
어떻게 구현하고자 하시는지 이해하지 못하였는데요
JWT는 카카오와 무관하게 서비스측 인가용으로 spring에서 발급하시는 것으로 보입니다. access, refresh는 카카오 것이 아니라고 말씀하셨는데 이들 값이 왜 필요한지 문의 드렸습니다.
atrix
5월 24, 2024, 7:29오전
16
답변 감사합니다!
제가 생각한 로직입니다!
프론트(리액트)에서 로그인 요청(하이퍼링크를 통해)
OAuth2 로그인을 이용해 로그인(백엔드로 리다이렉트)
성공시 백엔드 SuccessHandler에서 access(안에 유저의 권한이나 아이디가 담김), refresh 토큰을 생성(access는 서비스 인가용 ex 글쓰기, 수정, 삭제, refresh는 access재발급용)
생성한 토큰들을 프론트로 전달(access는 url을 통해, refresh는 쿠키를 통해)
프론트에서 인가가 필요한(CRUD) api요청 시 4에서 전달 받은 access를 헤더에 담아 api 요청
혹시 제가 로직에 대해 잘 못 이해하고 있는걸까요??
또한 OAuth2에서 제공한 토큰은 유저 정보 획득용이라고 생각했습니다.
카카오에서 제공하는 접근 토큰은 말씀처럼 사용자 정보 및 기능 접근용으로 제공됩니다.
서비스에서 서비스측 API사용을 위한 access 토큰을 프론트로 전달할 때, 서비스가 웹에서만 제공된다면 일반적으로 쿠키로 전달합니다.
url이나 다른 방식으로 전달하고 이후 API 요청마다 authorization 헤더에 담아 사용할 수도 있지만, 쿠키로 응답 하였다면 이후 API 사용시 헤더로 따로 전달하지 않아도 되기에 일반적으로 쿠키로 전달합니다.
다만, 일반적인 예시이며 어떠한 방법이 더 좋거나 하지는 않습니다. 서비스 구현 내용에 따라 선택하시면 됩니다.
이어서 refresh 토큰은 보안을 위해 일반적으로 프론트로 전달하지 않습니다.
토큰이 만료되면 보통 사용자 인증을 다시 요청합니다.
만약, 서비스가 네이티브 앱으로 제공되기에 토큰 갱신 용도로 프론트로 전달하고자 하는 것이라면 이런한 방식을 고려하셔도 무관합니다.
비슷한 예로 네이티브 앱 환경을 위해 제공되는 카카오의 SDK에서는 access 토큰과 refresh 토큰을 클라이언트가 갖고 있다가 적절한 시점에 갱신 합니다.
atrix
5월 24, 2024, 7:59오전
18
상세한 답변 너무 감사합니다!!
위 말씀에서 사용자 인증을 다시 요청한다는 말은 새로 로그인을 요구한다는 말씀이실까요?
만약 새로 로그인을 요청하는거라면 refresh 토큰을 굳이 생성할 필요가 없는걸까요? refresh 토큰은 access토큰 재발급용으로 알고 있어 여쭤봅니다!
access token 갱신을 위해 refresh token을 구성하는건 맞지만
일반적으로 웹서비스만 제공되는 환경에서는 보안을 위해 refresh token을 클라이언트에 두지 않습니다.
보통 새로 로그인 하도록 하거나, 브라우저 세션에서만 유효하도록 쿠키로 제어합니다.
프론트에 리프래시 토큰을 두고 계속 갱신할 수 있도록 하고자 한다면, 탈취를 대비하여 각별한 보안 처리가 필요 합니다.
1개의 좋아요
atrix
5월 24, 2024, 8:34오전
20
귀찮으셨을 텐데 계속해서 친절한 답변 감사합니다!