0

I am building Android App which shows Withings user's activity data in my Application.

But when I am trying to call refresh_token url:

https://oauth.withings.com/account/request_token?oauth_callback=******&oauth_consumer_key=******&oauth_nonce=******&oauth_signature=CcMrI7JaI8M5tEenye3s95wx%2BZ4%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1477386344&oauth_version=1.0

Then I am getting Invalid Signature response like below:

{
   "status":0,
   "message":"Invalid signature :\n CcMrI7JaI8M5tEenye3s95wx+Z4= .. \n{\"oauth_callback\":\"******\",\"oauth_consumer_key\":\"ce54bd6c671546ef8f8d394c0db4bd86688289d5f7fb39f371c5ebce4d01\",\"oauth_nonce\":\"f339febe0fdf4b53b953501e45a049db\",\"oauth_signature\":\"CcMrI7JaI8M5tEenye3s95wx+Z4=\",\"oauth_signature_method\":\"HMAC-SHA1\",\"oauth_timestamp\":\"1477386344\",\"oauth_version\":\"1.0\"}\n{\"base_string\":\"GET&https%3A%2F%2Foauth.withings.com%2Faccount%2Frequest_token&oauth_callback%3D******%26oauth_consumer_key%3D******%26oauth_nonce%3Df339febe0fdf4b53b953501e45a049db%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1477386344%26oauth_version%3D1.0\"}\n{\"key\":\"******\",\"secret\":\"******\",\"callback_url\":null}"
}
Rohan Khude
  • 4,455
  • 5
  • 49
  • 47
Nikita Shah
  • 156
  • 10

1 Answers1

1

First of all you can use the scribe lib
On my sample code I have an Authentication Activity that has an WebView that the user uses to verify the app. Then that Authentication Activity sends back to the MainActivity the response.

On my example I am storing locally on a DB the authenticated user to not ask every time the credentials.
Also I am sending the access token to python server that will get all data stored on Withings Cloud to save it to my Server DB and represent them on a Graph Activity. {I have removed that part}

Because of the copy paste maybe something is missing but most of the code is here

public class WithingsApi extends DefaultApi10a {

    private static final String AUTHORIZATION_URL ="https://oauth.withings.com/account/authorize?oauth_token=%s";
    private static final String apiKey = "API_KEY";
    private static final String apiSecret = "API_SECRET";

    @Override
    public String getRequestTokenEndpoint() {
        return "https://oauth.withings.com/account/request_token";
    }

    @Override
    public String getAccessTokenEndpoint() {
        return "https://oauth.withings.com/account/access_token";
    }

    @Override
    public String getAuthorizationUrl(Token requestToken) {
        return String.format(getAUTHORIZATION_URL(), requestToken.getToken());
    }

    public static String getKey(){
        return apiKey;
    }

    public static String getSecret(){
        return apiSecret;
    }

    public static String getAUTHORIZATION_URL() {
        return AUTHORIZATION_URL;
    }

}




@SuppressLint("SetJavaScriptEnabled")
public class AuthenticationActivity extends Activity {
    final String LOGTAG = "WITHINGS";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_authentication);

        final WebView wvAuthorise = (WebView) findViewById(R.id.wvAuthorise);
        wvAuthorise.getSettings().setJavaScriptEnabled(true);
        wvAuthorise.setWebViewClient(new MyWebViewClient(wvAuthorise));

        MainActivity.service = new ServiceBuilder().provider(WithingsApi.class)
                .apiKey(WithingsApi.getKey())
                .apiSecret(WithingsApi.getSecret())
                .build();

        new Thread(new Runnable() {
            public void run() {
                MainActivity.requestToken = MainActivity.service.getRequestToken();
                final String authURL = MainActivity.service.getAuthorizationUrl(MainActivity.requestToken);
                wvAuthorise.post(new Runnable() {
                    @Override
                    public void run() {
                        wvAuthorise.loadUrl(authURL);
                    }
                });             

            }
        }).start();

    }

    class MyWebViewClient extends WebViewClient{
        WebView wvAuthorise;
        MyWebViewClient(WebView wv){
            wvAuthorise = wv;
        }
        @Override
        public void onPageFinished(WebView view, String url) {
                getUSERID(url);
        }
    }

    private void getUSERID(final String url) {

        try {
            String divStr = "userid=";
            int first = url.indexOf(divStr);

            if(first!=-1){
                final String userid = url.substring(first+divStr.length());

                Intent intent = new Intent();
                intent.putExtra("USERID",userid);
                setResult(RESULT_OK,intent);
                finish();
            }
            else
            {
                //...
            }

        } catch (Exception e) {
            Log.e(LOGTAG,e.getMessage());
            //...
        }
    }
}



public class MainActivity extends FragmentActivity {

    public static OAuthService service;
    public static Token requestToken;
    String secret, token;
    Token accessToken;
    String userId = "";

    private UsersDataSource datasource;
    private TextView nameTV;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        _mainActivity = this;

        nameTV = (TextView) findViewById(R.id.nameTitleTextView);
        nameTV.setText("--");

        getCredentials();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode,
            Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);

        if (requestCode == AUTHENTICATION_REQUEST) {

            if (resultCode == RESULT_OK) {
                Bundle extras = intent.getExtras();
                if (extras != null) {
                    userId = extras.getString("USERID");

                    getAccessTokenThread.execute((Object) null);
                }
            }
        }
    }
    @Override
    protected void onResume() {
        datasource.open();
        super.onResume();
    }

    @Override
    protected void onPause() {
        datasource.close();
        super.onPause();
    }

    private void getCredentials() {
        try {
            datasource = new UsersDataSource(this);
            datasource.open();

            List<User> users = datasource.getAllUsers();

            if (users.isEmpty()) {
                startAuthenticationActivity();
            } else {
                // TODO load all users and if isn't anyone correct
                // startAuthenticationActivity
                secret = users.get(0).getSecret();
                token = users.get(0).getToken();
                userId = users.get(0).getUserId();
                Log.i(LOGTAG, "secret  : " + secret);
                Log.i(LOGTAG, "token  : " + token);
                Log.i(LOGTAG, "userId  : " + userId);
                try {
                    service = new ServiceBuilder().provider(WithingsApi.class)
                            .apiKey(WithingsApi.getKey())
                            .apiSecret(WithingsApi.getSecret()).build();
                    accessToken = new Token(token, secret);

                    loadData();
                } catch (Exception ex) {
                    startAuthenticationActivity();
                }

            }
        } catch (Exception ex) {
            Log.e(LOGTAG, "try on create" + ex.getLocalizedMessage());
        }
    }

    private void startAuthenticationActivity() {
        Intent intent = new Intent(this,
                ics.forth.withings.authentication.AuthenticationActivity.class);
        startActivityForResult(intent, AUTHENTICATION_REQUEST);
    }

    AsyncTask<Object, Object, Object> getAccessTokenThread = new AsyncTask<Object, Object, Object>() {
        @Override
        protected Object doInBackground(Object... params) {
            accessToken = service
                    .getAccessToken(requestToken, new Verifier(""));

            secret = accessToken.getSecret();
            token = accessToken.getToken();
            return null;
        }

        @Override
        protected void onPostExecute(Object result) {
            // authentication complete send the token,secret,userid, to python
            datasource.createUser(token, secret, userId);
            loadData();
        };

    };
}

UPDATE
OAuthService class is from Scribe
Token class is from Scribe
UserDataSource class is a DB Helper Class more here

gmetax
  • 3,853
  • 2
  • 31
  • 45
  • Thanks @metax, I'll try this code but can you provide OAuthService class, Token class and UserDataSource classes you are using in MainActivity? – Nikita Shah Oct 27 '16 at 03:47
  • And I'm getting Invalid signature on First step of Withings API authorization i.e getting oAuth url. – Nikita Shah Oct 27 '16 at 03:48
  • Thanks a lot @gmetax, It worked, I got user id from withings. – Nikita Shah Oct 27 '16 at 06:41
  • I have updated my answer for the classes, if you want anything more ask me. – gmetax Oct 27 '16 at 08:22
  • 1
    Yes after importing scribe I got all the info. Thanks a lot for your help. Withings is perfactly working now. – Nikita Shah Oct 27 '16 at 09:31
  • it is sad that there isn't anything for that online. If you want you can push your project to a github repository so it will be a helper for anyone who needs help. Mine Project is "huge" with too much activities that I cannot remove right now so I just copy paste 3 classes to help you. – gmetax Oct 27 '16 at 09:36
  • Yes, I will definitely do it in a very short time as I tried all your given code to a demo but like rough work, so I'll make it in a good format and then will push it to GitHub. Thanks once again. – Nikita Shah Oct 27 '16 at 09:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126808/discussion-between-nikita-shah-and-gmetax). – Nikita Shah Oct 27 '16 at 09:39
  • It's a too late in this so. I have above code but some of the methods are not available in scribe library. can you suggest some link where i can get all these stuff. – Suraj Bahadur Apr 05 '19 at 15:04