비바톤 로그인 진행 과정

1. 인증코드 요청

인증 코드 요청은 비바톤 로그인 화면을 호출하고, 사용자 로그인을 거쳐 인증 코드 발급을 요청하는 API입니다. 비바톤 로그인을 시작하는 단계로써, 이 기능은 비바톤 서버에 로그인한 계정 세션이 존재하는지에 따라 인증 단계가 달라집니다. 비바톤 서버에 계정 세션이 없다면, 사용자는 계정 ID 및 비밀번호를 입력해 로그인하는 화면을 보게 되고, 계정 세션이 있는 상태라면 곧바로 코드를 받게 됩니다.

인증코드 요청시에 파라미터 정보가 올바르지 않을 경우는 아래와 같은 화면이 표시될 수 있습니다.

페이지를 찾을 수 없습니다.
페이지의 주소가 변경 혹은 삭제되어 요청하신 페이지를 찾을 수 없습니다.
입력하신 주소가 정확한지 다시한번 확인해주시기 바랍니다.

URL

GET /oauth/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&response_type=code&scope=read_profile
Host: bauth.bbaton.com

Parameter

요청 변수명 타입 필수 여부 기본값 설명
client_id string Y 애플리케이션 등록 시 발급받은 Client_id 값
redirect_uri string Y 애플리케이션을 등록 시 입력한 Callback URL
response_type string Y code 인증 과정에 대한 내부 구분값으로 ‘code’로 전송해야 함
scope string Y read_profile 접근 허용 범위 값으로 ‘read_profile’로 전송해야 함

Response

타입 설명
Code string 토큰 요청시에 필요한 인증 코드

Code

window.onload = function() {
    //메인 페이지
    location.href = "https://bauth.bbaton.com/oauth/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&response_type=code&scope=read_profile";
    //팝업
    window.open("https://bauth.bbaton.com/oauth/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&response_type=code&scope=read_profile", "bbaton", "width=400, height=500");
}

※ 비바톤 인증 코드 요청 Callback 정보
비바톤 아이디로 로그인 인증 요청URL을 호출했을 때 사용자가 비바톤에 로그인하지 않은 상태이면 Bbaton 로그인 화면으로 이동하고, 사용자가 비바톤에 로그인한 상태이면 콜백 URL에 code값이 문자열로 전송됩니다. code 값은 토큰 요청에 사용합니다.

– 인증 요청 성공시 : http://redirect_uri?code={CODE}

2. Redirect Url 로 인증코드 받기

인증 코드 요청의 응답은 redirect_uri로 Redirect되며, Location에 인증 코드가 담긴 쿼리 스트링(Query String) 또는 에러 메시지를 포함합니다. 클라이언트 서버는 redirect_uri로 받은 요청을 처리해 인증 코드를 얻거나 상황에 맞는 페이지를 보여주도록 처리해야 합니다. 받은 인증 코드는 토큰 요청에 사용합니다.

Redirect_uri 설정 확인하기

처음 비바톤 로그인을 구현하고 인증 코드 받기를 요청했을 때, “사이트에 연결할 수 없음” 에러가 발생하는 경우가 많습니다. 이 에러는 인증 코드 발급 요청 시 전달된 redirect_uri가 앱 정보에 등록된 값과 다를 때 발생합니다. Redirect URI 등록 가이드를 참고해 실제 비바톤 로그인 절차를 수행하는 웹 페이지 등의 OAuth Redirect URI를 입력해야 합니다. 이미 Redirect URI 등록을 했다면, 에러 메시지를 통해 실제 요청 시 파라미터로 전달된 redirect_uri 값을 확인하여 등록된 값과 완전히 일치하는지 비교합니다.

3. 인증코드로 토큰 요청

인증 코드를 받은 뒤, 인증 코드로 토큰을 요청하는 API입니다. 인증 코드 받기만으로는 비바톤 로그인이 완료되지 않으며, 토큰 요청까지 마쳐야 토큰으로 사용자 정보를 요청 할 수 있습니다.

필수 파라미터 값들을 담아 POST로 요청합니다. 요청 성공 시, 응답은 JSON 객체로 전달되며 사용자 토큰 값과 타입, 초 단위로 된 만료 시간을 포함하고 있습니다.

참고: 비바톤계정 세션의 인증 시간

로그인 시 비바톤계정 세션의 인증 시간은 기본 24시간이며, 최초 인증 후 세션 시간은 변경되지 않습니다.

URL

POST /oauth/token
Host: bauth.bbaton.com
Content-type: application/x-www-form-urlencoded

Parameter

요청 헤더명 설명
Authorization Basic {CLIENT_ID}:{CLIENT_SECRET}
{CLIENT_ID}:{CLIENT_SECRET}는 Base64로 인코딩 해서 전송
요청 변수명 타입 필수 여부 기본값 설명
grant_type string Y 인증 과정에 대한 내부 구분값으로 ‘authorization_code’로 전송해야 함
redirect_uri string Y 애플리케이션을 등록 시 입력한 Callback URL
code string Y 인증 코드 받기 요청으로 얻은 인증 코드

Response

타입 설명
access_token string 사용자 액세스 토큰 값
token_type string 토큰 타입, “bearer”로 고정
expires_in integer 액세스 토큰 만료 시간(초)
scope string 인증된 사용자의 정보 조회 권한 범위

Code

//API신청시의 Redirect uri : http://{REDIRECT_URI}?code={CODE}
app.get("API신청시의 Redirect uri 경로", (req, res) => {
    const url = "https://bauth.bbaton.com/oauth/token";
    const client_id = "API신청후 받은 client id 값";
    const secret_key = "API신청후 받은 secret_key 값";
    const redirect_uri = "API신청시의 Redirect uri 값";
    const code = req.query.code;
    const auth = "Basic " + new Buffer.from(client_id + ":" + secret_key).toString("base64");
    const options = {
        uri: url,
        method: "POST",
        headers: {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": auth
        },
        qs:{
            grant_type: "authorization_code",
            redirect_uri: redirect_uri,
            code: code,
        }
    };
    request(options, function (err, response, body) {
        if (response.statusCode == "200") {
            //토큰 호출 성공
            JSON.parse(body).token_type;
            JSON.parse(body).access_token;
        } else {
            //토큰 호출 실패
        }
    });
});
//API신청시의 Redirect uri : http://{REDIRECT_URI}?code={CODE}
@GetMapping(value = "API신청시의 Redirect uri 경로")
public String redirect(HttpServletRequest request, @RequestParam String code) throws ParseException {
    RestTemplate restTemplate = new RestTemplate();
    String credentials = "API신청후 받은 client id 값:API신청후 받은 secret_key 값";
    String encodedCredentials = new String(Base64.encodeBase64(credentials.getBytes()));
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    headers.add("Authorization", "Basic " + encodedCredentials);
    MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
    params.add("code", code);
    params.add("grant_type", "authorization_code");
    params.add("redirect_uri", "API신청시의 Redirect uri 값");
    HttpEntity<MultiValueMap<String, String>> requestParams = new HttpEntity<>(params, headers);
    ResponseEntity response = restTemplate.postForEntity("https://bauth.bbaton.com/oauth/token", requestParams, String.class);
    if (response.getStatusCode() == HttpStatus.OK) {
        //토큰 호출 성공
        JSONParser parser = new JSONParser();
        JSONObject jsonBody = (JSONObject) parser.parse(response.getBody());
        String token_type = (String)jsonBody.get("token_type");
        String accessToken = (String)jsonBody.get("access_token");
        return "index"
    } else {
        //토큰 호출 실패
        return "error";
    }
}
//API신청시의 Redirect uri : http://{REDIRECT_URI}?code={CODE}
$client_id = "API신청후 받은 client id 값";
$secret_key = "API신청후 받은 secret_key 값";
$redirect_uri = "API신청시의 Redirect uri값";
$code = $_GET["code"];
$url = "https://bauth.bbaton.com/oauth/token";

$param = array(
    "grant_type"=>"authorization_code",
    "redirect_uri"=>$redirect_uri,
    "code"=>$code,
);

$headers = array(
   "Authorization: Basic ".base64_encode($client_id.":".$secret_key)
);

$cu = curl_init();
curl_setopt($cu, CURLOPT_URL, $url);
curl_setopt($cu, CURLOPT_POST, 1);
curl_setopt($cu, CURLOPT_POSTFIELDS, http_build_query($param));
curl_setopt($cu, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($cu, CURLOPT_TIMEOUT, 60);
curl_setopt($cu, CURLOPT_HEADER, true);
curl_setopt($cu, CURLOPT_HTTPHEADER, $headers);
$token = curl_exec($cu);
curl_close($cu);

$txt_start = strpos($token, "{");
$json_txt = substr($token, $txt_start);
$json_token = json_decode($json_txt, true);
$access_token = $json_token["access_token"];
#API신청시의 Redirect uri : http://{REDIRECT_URI}?code={CODE}
@app.get("API신청시의 Redirect uri 경로")
async def redirect(code):
    url = "https://bauth.bbaton.com/oauth/token"
    client_id = "API신청후 받은 client id 값"
    secret_key = "API신청후 받은 secret_key 값"
    redirect_uri = "API신청시의 Redirect uri 값"
    d = {"grant_type": "authorization_code", "redirect_uri": redirect_uri, "code": code}
    h = {"Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic %s" % base64.b64encode((client_id  + ":" + secret_key).encode("utf-8")).decode("utf-8")}
    res = requests.post(url, headers=h, data=d)
    if res.status_code == 200:
        res.json()["token_type"]
        res.json()["access_token"]
        return {"message": "토큰 호출 성공"}
    else:
        return {"message": "토큰 호출 실패"}

4. 토큰으로 사용자 정보 요청

현재 로그인한 사용자의 정보를 불러옵니다. 사용자 정보 요청 API는 사용자 액세스 토큰을 사용하는 방법을 제공합니다.

사용자 액세스 토큰을 헤더(Header)에 담아 GET으로 요청합니다. 사용자 정보 요청 성공시, 응답 바디(Body)는 JSON 객체로 사용자 정보들을 포함합니다.

사용자 정보 받기에 성공하여 비바톤 로그인을 완료했다면, 성인인증 및 로그인 등을 처리합니다.

URL

GET /v2/user/me
Host: bapi.bbaton.com

Parameter

요청 헤더명 설명
Authorization 접근 토큰(access token)을 전달하는 헤더
다음과 같은 형식으로 헤더 값에 접근 토큰(access token)을 포함합니다. 토큰 타입은 “Bearer”로 값이 고정되어 있습니다.
Authorization: {토큰 타입} {접근 토큰}

Response

타입 설명 기본
user_id string 사용자 아이디 사용자 아이디
adult_flag string 성인 여부 값 N/A
birth_year string 생년 N/A
gender string 성별 N/A
income string 연소득 N/A
student string 학생 N/A

Code

//3번에서 받은 token_type, access_token
app.get("API신청시의 Redirect uri 경로", (req, res) => {
  const url = "https://bapi.bbaton.com/v2/user/me";
  const auth = JSON.parse(body).token_type + " " + JSON.parse(body).access_token;
  const options = {
      uri: url,
      method: "GET",
      headers: {
          "Authorization": auth
      }
  };
  
  request(options, function (err, response, body) {
      if (response.statusCode == "200") {
          //토큰 호출 성공
          if (JSON.parse(body).adult_flag == "Y") {
              //인증 성공 처리
          } else {
              //인증 실패 처리
          }
      } else {
          //토큰 호출 실패
      }
  });
});
//3번에서 받은 token_type, access_token
@GetMapping(value = "API신청시의 Redirect uri 경로")
public String callback(HttpServletRequest request, @RequestParam String code) throws ParseException {
    //3번에서 받은 token_type, access_token
    String token_type = (String)jsonBody.get("token_type");
    String accessToken = (String)jsonBody.get("access_token");
    RestTemplate restTemplate = new RestTemplate();
    HttpHeaders headers = new HttpHeaders();
    headers.set("Authorization", token_type + " " + accessToken);
    HttpEntity entity = new HttpEntity(headers);
    ResponseEntity certificationsInfo = restTemplate.exchange("https://bapi.bbaton.com/v2/user/me", HttpMethod.GET, entity, String.class);
    if (certificationsInfo.getStatusCode() == HttpStatus.OK) {
        JSONParser parser = new JSONParser();
        JSONObject jsonBody = (JSONObject) parser.parse(certificationsInfo.getBody());
        String adultFlag = (String)jsonBody.get("adult_flag");
        if ("Y".equals(adultFlag)) {
            //인증 성공 처리
        } else {
            //인증 실패 처리
        }
        return "index";
    } else {
        return "error";
    }
}
//3번에서 받은 access_token
$access_token = $json_token["access_token"];
$url = "https://bapi.bbaton.com/v2/user/me";

$headers = array(
    "Authorization: Bearer " .$access_token
);

$cu = curl_init();
curl_setopt($cu, CURLOPT_URL, $url);
curl_setopt($cu, CURLOPT_POST, 0);
curl_setopt($cu, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($cu, CURLOPT_TIMEOUT, 60);
curl_setopt($cu, CURLOPT_HEADER, true);
curl_setopt($cu, CURLOPT_HTTPHEADER, $headers);
$user = curl_exec($cu);
curl_close($cu);

$txt_start = strpos($user, "{");
$json_txt = substr($user, $txt_start);
$json_user = json_decode($json_txt, true);

if ($json_user["adult_flag"] == "Y") {
    //인증 성공 처리
} else {
    //인증 실패 처리
}

//팝업시 처리
echo "";
#3번에서 받은 token_type, access_token
@app.get("API신청시의 Redirect uri 경로")
async def redirect(code):
    url = "https://bapi.bbaton.com/v2/user/me"
    auth = res.json()["token_type"] + " " + res.json()["access_token"]
    h = {"Authorization": auth}
    res = requests.get(url, headers=h)
    if res.status_code == 200:
        if res.json()["adult_flag"] == "Y":
            #인증 성공처리
        else:
            #인증 실패처리
        return {"message": "호출 성공"}
    else:
        return {"message": "호출 실패"}

공통 조회 시 에러

HTTP코드 에러코드 에러 메시지 조치방안
401 Invalid_token Cannot convert access token to JSON Access token을 확인해 주세요.
403 invalid_request Wrong Param or request statement 요청하신 파라메터를 확인해주세요.
404 Not Found 호출 주소를 확인해주세요.
500 Internal Server Error 서버의 동작에서 발생하는 에러 입니다.
503 Service Unavailable 서버쪽 문제로 인하여 서비스가 현재 불가능한 상태입니다.