Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

"errorType":"insufficient_scope" when sending valid token

Hello. I am trying to integrate an web application with the fitbit server. I have a java client to connect with the fitbit server. This client are using  HttpClient from Apache. When i have the token, and i try to get a resource from the fitbit server, the service response is this:
 success = false
  errors = [{"errorType":"insufficient_scope","message":"This application does not have permission to access profile data. Visit https:\/\/dev.fitbit.com\/docs\/oauth2 for more information on the Fitbit Web API authorization process."}]
This is an segment of code:
    HttpClient client = HttpClientBuilder.create().build();
    HttpPost post = new HttpPost("https:\/\/api.fitbit.com\/1\/user/###GST\/profile.json");
    post.addHeader("Authorization", "Bearer " + "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NTgxMDIxMTcsInNjb3BlcyI6IiIsImF1ZCI6IjIyN0dTVCIsImlzcyI6IkZpdGJpdCIsInR5cCI6ImNsaWVudF9hY2Nlc3NfdG9rZW4iLCJpYXQiOjE0NTgwOTg1MTd9.I1m2LSxVW064-MD-gGu-BP9rf8Y2TFJDRWWLQjcfb30TOKEN RECUPERADO: eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NTgxMDIxMTcsInNjb3BlcyI6IiIsImF1ZCI6IjIyN0dTVCIsImlzcyI6IkZpdGJpdCIsInR5cCI6ImNsaWVudF9hY2Nlc3NfdG9rZW4iLCJpYXQiOjE0NTgwOTg1MTd9.I1m2LSxVW064-MD-gGu-BP9rf8Y2TFJDRWWLQjcfb30");
    List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>();
    parametersBody.add(new BasicNameValuePair("scope", "activity nutrition heartrate location profile settings sleep social weight"));
    post.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8));
    HttpResponse respuesta = client.execute(post);
    int statusCode = respuesta.getStatusLine().getStatusCode();
    System.out.println("statusCode=" + statusCode);
    ..
I have doubt around of the URL format that i used to get the resource.
Is "https:\/\/api.fitbit.com\/1\/user\/###GST\/profile.json an correct format?"
Where i can to find an list of URL formats. I have an fitbit flex and i want to view my information from my own server

Anybody know how to connect to fitbit from java, some recomendation?
Thanks 

Best Answer
0 Votes
3 REPLIES 3

Hi,

 

you have to define permissions scopes during authetication. Try to look to documentations https://dev.fitbit.com/docs/oauth2/#scope When you are trying to access users profile, you have to authorize with `profile scope`

Best Answer

Hi,
This is the code that was executed to get access to my fitbit resources. In the Authentication method, i sent the scope.

public class Controlador extends HttpServlet {

  /**
   * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
   *
   * @param request servlet request
   * @param response servlet response
   * @throws ServletException if a servlet-specific error occurs
   * @throws IOException if an I/O error occurs
   */
  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    try {
      /* Preparar el llamado al servicio de autenticación de  */
      out.println("<!DOCTYPE html>");
      out.println("<html>");
      out.println("<head>");
      out.println("<title>Servlet Controlador</title>");
      out.println("</head>");
      out.println("<body>");

      authenticate(response, out);

      out.println("<h1>Servlet Controlador at " + request.getContextPath() + "</h1>");
      out.println("</body>");
      out.println("</html>");
    } finally {
      out.close();
    }
  }

  private void authenticate(HttpServletResponse response, PrintWriter out) throws IOException, UnsupportedEncodingException {
    RequestConfig requestConfig = RequestConfig.custom()
            .setSocketTimeout(20000)
            .setConnectTimeout(20000)
            .setConnectionRequestTimeout(20000)
            .build();
    HttpClient client = HttpClientBuilder.create().build();
    HttpPost post = new HttpPost("https:\/\/www.fitbit.com\/oauth2\/authorize");
    post.addHeader("Authorization", "Basic " + Base64Encoded.encodeCredentials("###GST", "##def6b512cb895acab98b119bf8d064"));

    List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>();
    parametersBody.add(new BasicNameValuePair(OAuthConstants.RESPONSE_TYPE, "code"));
    parametersBody.add(new BasicNameValuePair(OAuthConstants.CLIENT_ID, "###GST"));
    parametersBody.add(new BasicNameValuePair(OAuthConstants.REDIRECT_URI, "http://localhost:8084/ConsolidadorBiomedicoServer/handler"));
    parametersBody.add(new BasicNameValuePair(OAuthConstants.SCOPE, "activity nutrition heartrate location nutrition profile settings sleep social weight"));
    parametersBody.add(new BasicNameValuePair(OAuthConstants.CLIENT_SECRET, "##def6b512cb895acab98b119bf8d064"));

    post.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8));
    post.setConfig(requestConfig);
    HttpResponse respuesta = client.execute(post);
    int statusCode = respuesta.getStatusLine().getStatusCode();
    System.out.println("statusCode primer llamado: " + statusCode);
    if (OAuthConstants.HTTP_SEND_REDIRECT == statusCode) {
      /*Todos los headers*/
      System.out.println("---------------- Headers ------------------");
      for (int i = 0; i < respuesta.getAllHeaders().length; i++) {
        System.out.println(respuesta.getAllHeaders()[i]);
      }
      System.out.println("---------------- Fin Headers ------------------");
      String location = getHeader(respuesta.getAllHeaders(), OAuthConstants.LOCATION_HEADER);
      String code = getHeader(respuesta.getAllHeaders(), OAuthConstants.CODE);
      System.out.println("Code="+code);
      System.out.println("Location: " + location);
    }

    System.out.println("statusCode=" + statusCode);
    String location = getHeader(respuesta.getAllHeaders(), OAuthConstants.LOCATION_HEADER);
    System.out.println("location: " + location);

    /*------------------- funciona ------------------------*/
    String codificaRedirec = URLEncoder.encode("response_type=code&client_id=###GST&scope=activity heartrate location nutrition profile settings sleep social weight", HTTP.UTF_8);
    String token = recuperaToken(/*out*/);
    System.out.println("TOKEN RECUPERADO: " + token);
    try {
      recuperarRecurso(out, token);
    } catch (Exception e) {
      System.out.println("IOException");
      e.printStackTrace();
    }
    response.sendRedirect(location + codificaRedirec);
  }

  private String recuperarRecurso(PrintWriter out, String token) throws IOException, UnsupportedEncodingException {
    RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(20000)
            .setConnectTimeout(20000)
            .setConnectionRequestTimeout(20000)
            .build();
    System.out.println("====================================================================================");

    HttpClient client = HttpClientBuilder.create().build();
//    HttpGet get = new HttpGet("https:\/\/api.fitbit.com\/1\/user\/-\/activities\/date\/2016-03-02.json");
    HttpGet get = new HttpGet("https:\/\/api.fitbit.com\/1\/user\/-\/profile.json");
    get.addHeader("Authorization", "Bearer " + token);
    get.setConfig(requestConfig);
    HttpResponse respuesta = client.execute(get);
    int statusCode = respuesta.getStatusLine().getStatusCode();
    System.out.println("statusCode=" + statusCode);
    String location = getHeader(respuesta.getAllHeaders(), OAuthConstants.LOCATION_HEADER);
    System.out.println("location: " + location);
    System.out.print("statusCode=" + statusCode);
    /*Recupera el token de acceso*/
    System.out.print("DATOS RECUPERADOS");
    try {
      HttpEntity entidad = respuesta.getEntity();
      System.out.println(entidad.toString());
      Map<String, String> map = handleResponse(respuesta);
      for (Map.Entry<String, String> entry : map.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue();
        System.out.print("Key=" + key + " | value=" + value);
        System.out.println("Key=" + key + " | value=" + value);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return String.valueOf(statusCode);
  }

  private String recuperaToken(/*PrintWriter out*/) throws IOException, UnsupportedEncodingException {
    RequestConfig requestConfig = RequestConfig.custom()
            .setSocketTimeout(20000)
            .setConnectTimeout(20000)
            .setConnectionRequestTimeout(20000)
            .build();
    HttpClient client = HttpClientBuilder.create().build();
    HttpPost post = new HttpPost("https:\/\/api.fitbit.com\/oauth2\/token");
    post.addHeader("Authorization", "Basic " + Base64Encoded.encodeCredentials("###GST", "##def6b512cb895acab98b119bf8d064"));
    List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>();
    parametersBody.add(new BasicNameValuePair(OAuthConstants.CLIENT_ID, "###GST"));
    parametersBody.add(new BasicNameValuePair(OAuthConstants.GRANT_TYPE, "client_credentials"));
    parametersBody.add(new BasicNameValuePair("redirect_uri", "http://localhost:8084/ConsolidadorBiomedicoServer/handler"));
    parametersBody.add(new BasicNameValuePair(OAuthConstants.SCOPE, "activity nutrition heartrate location nutrition profile settings sleep social weight"));
    parametersBody.add(new BasicNameValuePair(OAuthConstants.CLIENT_SECRET, "##def6b512cb895acab98b119bf8d064"));

    post.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8));
    post.setConfig(requestConfig);
    HttpResponse respuesta = client.execute(post);
    int statusCode = respuesta.getStatusLine().getStatusCode();
    System.out.println("statusCode=" + statusCode);
    String location = getHeader(respuesta.getAllHeaders(), OAuthConstants.LOCATION_HEADER);
    System.out.println("location: " + location);
    System.out.print("statusCode=" + statusCode);
    /*Recupera el token de acceso*/
    Map<String, String> map = handleResponse(respuesta);
    String accessToken = map.get(co.edu.javeriana.misyc.smrpn.fitbit.OAuthConstants.ACCESS_TOKEN);
    System.out.print("TOKEN DE ACCESO REGRESADO:");
    System.out.print(accessToken);
    return accessToken;

  }

  // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
  /**
   * Handles the HTTP <code>GET</code> method.
   *
   * @param request servlet request
   * @param response servlet response
   * @throws ServletException if a servlet-specific error occurs
   * @throws IOException if an I/O error occurs
   */
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
    processRequest(request, response);
  }

  /**
   * Handles the HTTP <code>POST</code> method.
   *
   * @param request servlet request
   * @param response servlet response
   * @throws ServletException if a servlet-specific error occurs
   * @throws IOException if an I/O error occurs
   */
  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
    processRequest(request, response);
  }

  /**
   * Returns a short description of the servlet.
   *
   * @return a String containing servlet description
   */
  @Override
  public String getServletInfo() {
    return "Short description";
  }// </editor-fold>

}

where will be the problem?

Please helpme.

Best Answer
0 Votes

can someone help me please?

Best Answer
0 Votes