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 AnswerHi,
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`
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