토큰 저장

1. 시작하며 
 Swit API를 사용하기 위해서는 기본적으로 토큰이 필요 합니다.
자세한 사항은 Swit Developers의 OAuth flow 를 참조해 주세요 
 
 2. 토큰의 저장 
 
 본 예제에서는 Access token과 Refresh token을 데이터 베이스에 저장하도록 하겠습니다. 
 먼저 Token을 담을 객체를 작성하겠습니다. 
 
 
 3. 토큰 객체 생성 
 3.1. SwitTokenEntity 
 package io.swit.api.model.entity.eai;

import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Entity
@Data
@Table(name = "swit_token")
@NoArgsConstructor(access = AccessLevel.PUBLIC)
public class SwitTokenEntity {

 @Id
 @Column(name = "token_id", nullable = false, length = 30)
 private String tokenId = "SWIT";

 @Column(name = "access_token", length = 500, nullable = false)
 private String accessToken;

 @Column(name = "refresh_token", length = 500, nullable = false)
 private String refreshToken;

 @Column(name = "expire_in", nullable = true)
 private Long expireIn;

 @Column(name = "scope", length = 100, nullable = true)
 private String scope;

 @Column(name = "token_type", length = 50, nullable = false)
 private String tokenType;

}
 
 
 swit_token 테이블을 데이터베이스에 생성해 줍니다. 
 
 3.2. SwitTokenDto 
 package io.swit.api.model.dto.eai;

import io.swit.api.model.entity.eai.SwitTokenEntity;
import lombok.Data;

@Data
public class SwitTokenDto {
 /** 토큰 아이디 */
 private String tokenId;

 /** 접근 토큰 */
 private String accessToken;

 /** 재인증 토큰 */
 private String refreshToken;

 /** 만료시간 */
 private Long expireIn;

 /** 인증 점위 */
 private String scope;

 /** 토큰 타입 */
 private String tokenType;

 /**
 * 엔티티 변환
 * @return 스윗 유저 토큰 엔티티
 */
 public SwitTokenEntity toEntity() {
 SwitTokenEntity entity = new SwitTokenEntity();
 entity.setTokenId(tokenId);
 entity.setAccessToken(this.accessToken);
 entity.setRefreshToken(this.refreshToken);
 entity.setExpireIn(this.expireIn);
 entity.setScope(this.scope);
 entity.setTokenType(this.tokenType);
 return entity;
 }
}
 
 3.3. SwitTokenRepository 
 package io.swit.api.data.repository.eai;

import io.swit.api.model.entity.eai.SwitTokenEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface SwitTokenRepository extends JpaRepository<SwitTokenEntity, String> {
}

 
 3.4. AuthQuery 
 package io.swit.api.data.query.eai;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import io.swit.api.data.repository.eai.SwitTokenRepository;
import io.swit.api.model.dto.eai.SwitTokenDto;
import io.swit.api.model.entity.eai.QSwitTokenEntity;
import io.swit.api.model.entity.eai.SwitTokenEntity;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Repository;

@Repository
@AllArgsConstructor
public class AuthQuery {
 /**
 * 사용자 토큰 저장
 * @param param 사용자 토큰 파라미터
 * @throws Exception
 */
 public void saveSwitToken(SwitTokenDto param) throws Exception {
 this.switUserTokenRepository.save(param.toEntity());
 } 
}
 
 3.5. AuthService 
 package io.swit.api.service.eai;

import io.swit.api.data.query.eai.AuthQuery;
import io.swit.api.model.dto.eai.SwitTokenDto;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;

@Service
@AllArgsConstructor
@Slf4j
public class AuthService {
 private AuthQuery authQuery;
 /**
 * 사용자 토큰 저장
 * @param param 사용자 토큰 파라미터
 * @throws Exception
 */
 public void saveSwitToken(SwitTokenDto param) throws Exception {
 this.authQuery.saveSwitToken(param);
 }
}
 
 
 4. 인증 및 가져오기 
 4.1. 인증용 컨트롤러 작성 
 
 토큰을 요청하였을때 결과값을 받는 컨트롤러를 작성합니다. 
 토큰 요청은 Swit Developers 를 참조해 주시고, 소스 관련은 Customer Tech Support 팀의 Github를 참조해 주세요. 
 아래의 소스는 인증을 받아 토큰을 받는 예제 입니다. 
 
 @GetMapping(value = "/callback")
 public ResponseEntity<?> getOauthCallback(
 HttpServletRequest req,
 HttpServletResponse res,
 HttpSession session
 ) {
 String code = "";
 String state = "";
 SwitTokenDto retDto = new SwitTokenDto();

 WebClient webClient = WebClient.builder()
 .baseUrl(var.API_URL)
 .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
 .build();
 try {
 code = req.getParameter("code").trim();
 state = req.getParameter("state").trim();
 String redirectUri = req.getRequestURL().toString().replace("http://", "https://");

 MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
 body.add("grant_type", "authorization_code");
 body.add("code", code);
 body.add("client_id", var.CLIENT_ID);
 body.add("client_secret", var.CLIENT_SECRET);
 body.add("redirect_uri", redirectUri);

 String retVal = webClient.post()
 .uri(var.TOKEN_URL)
 .contentType(MediaType.APPLICATION_FORM_URLENCODED)
 .bodyValue(body)
 .retrieve()
 .bodyToMono(String.class)
 .block();

 JsonParser parser = new JsonParser();
 Object obj = parser.parse(retVal);
 JsonObject jsonObject = (JsonObject)obj;

 retDto.setAccessToken(jsonObject.get("access_token").toString().replace("\"", ""));
 retDto.setRefreshToken(jsonObject.get("refresh_token").toString().replace("\"", ""));
 retDto.setExpireIn(Long.parseLong(jsonObject.get("expires_in").toString()));
 retDto.setScope(jsonObject.get("scope").toString().replace("\"", ""));
 retDto.setTokenType(jsonObject.get("token_type").toString().replace("\"", ""));

 // 받아온 토큰을 데이터베이스에 저장한다.
 retDto.setTokenId("cts-api");
 this.authService.saveSwitToken(retDto);
 } catch (Exception e) {
 log.error(e.getMessage());
 return ResponseEntity.internalServerError().body(e.getMessage());
 }
 return ResponseEntity.ok(retDto);
 }
 
 
 결과값으로 다음과 같이 데이터베이스에 저장 된 것을 확인할 수 있습니다.
 
 
 
 4.2. 인증용 토큰 가져오기 
 
 데이터베이스에 저장한 인증키를 가져옵니다. 
 
 /**
 * DB에 저장된 토큰정보 가져오기
 * @param tokenId 가져올 토큰 아이디
 * @return 토큰 정보
 * @throws Exception 오류정보
 */
 public SwitTokenDto getSwitToken(String tokenId) throws Exception {
 QSwitTokenEntity sut = new QSwitTokenEntity("sut");
 JPAQuery<SwitTokenEntity> query = queryFactory.selectFrom(sut);
 SwitTokenDto tokenDto = new SwitTokenDto();

 BooleanBuilder where = new BooleanBuilder();
 where.and(sut.tokenId.eq(tokenId));

 tokenDto = query.select(
 Projections.bean(SwitTokenDto.class,
 sut.tokenId,
 sut.accessToken,
 sut.tokenType,
 sut.expireIn,
 sut.scope,
 sut.refreshToken
 )
 ).where(where).fetchFirst();
 return tokenDto;
 }

 
 
 받아온 토큰정보를 header에 넣어 사용하시면 됩니다.