box / box-android-sdk

Apache License 2.0
62 stars 68 forks source link

How to get BoxSession by AccessToken or RefreshToken #415

Closed ohs0612 closed 4 years ago

ohs0612 commented 4 years ago

Description of the Issue

Hi, I am wondering how can we achieve BoxSession by only AccessToken or RefreshToken or both tokens? Like this post (https://github.com/box/box-android-sdk/issues/18) said, we have previously managed our authentication process, so we want to skip the default authentication process.

I have found out that there is a constructor for BoxSession like this: /**

But I am confused about what does the "refreshProvider" means? And how to correctly get the BoxSession? Is there any sample to doing so?

I do appreciate it in advance.

Versions Used

Box Content SDK: implementation 'com.box:box-android-sdk:5.0.0' Android: Android Studio 3.5.1

ohs0612 commented 4 years ago

Any voice here?

PJSimon commented 4 years ago

Hi @ohs0612 , I just wanted to update you that we were a little slow to respond last week due to the release of our iOS SDK. We're catching up on things and will get back to you soon on this. Thanks for your patience! ~Patrick

ohs0612 commented 4 years ago

Hello @PJSimon , Thank you for your reply. I have found out this way as below, which I can successfully get the files and folders from my root folder by loadRootFolder method without the default authentication process once I have my own AccessToken beforehand.

However, now, I am trying to sort how to refresh accessToken out. I am trying to use the solutions, mentioned from this link: https://github.com/box/box-android-sdk/issues/344

But, the debug mode points out my app stops at this line: mBoxSession.setSessionAuthListener(new BoxAuthentication.AuthListener() {

And when I click pause, it seems like it keeps waiting at the stack trace here: (Object.java) public final native void wait(long millis, int nanos) throws InterruptedException;

I still keep getting the "401 unauthorized error" back, and none of the logs from BoxAuthentication.AuthListener() callbacks has been print out.

Below is my code snippet:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    BoxConfig.IS_LOG_ENABLED = true;
    configureClient();
    new Thread(){
        @Override
        public void run() {
            initSession();
        }
    }.start();
}

private void configureClient() {
    BoxConfig.CLIENT_ID = CLIENT_ID;
    BoxConfig.CLIENT_SECRET = CLIENT_SECRET;
    // needs to match redirect uri in developer settings if set.
    BoxConfig.REDIRECT_URL = REDIRECT_URL;
}

private void initSession() {
    mBoxSession = new BoxSession(this, ACCESS_TOKEN, new MyProvider());
    //mBoxSession = new BoxSession(this);
    mBoxApiFolder = new BoxApiFolder(mBoxSession);
    mBoxSession.setSessionAuthListener(new BoxAuthentication.AuthListener() {
        @Override
        public void onRefreshed(BoxAuthentication.BoxAuthenticationInfo info) {
            Log.d(TAG, "~~~  onRefreshed ~~~");// No print out while the accessToken expires.
        }

        @Override
        public void onAuthCreated(BoxAuthentication.BoxAuthenticationInfo info) {
            Log.d(TAG, "~~~ onAuthCreated ~~~");// No print out while the accessToken expires.
            mBoxApiFolder = new BoxApiFolder(mBoxSession);
            loadRootFolder();//for test
        }

        @Override
        public void onAuthFailure(BoxAuthentication.BoxAuthenticationInfo info, Exception ex) {
            Log.d(TAG, "~~~ onAuthFailure ~~~");// No print out while the accessToken expires.
        }

        @Override
        public void onLoggedOut(BoxAuthentication.BoxAuthenticationInfo info, Exception ex) {
            Log.d(TAG, "~~~ onLoggedOut ~~~");// No print out while the accessToken expires.
        }
    });
    mBoxSession.authenticate(this);
    try {
        mBoxSession.refresh().get();
    } catch (Exception e){
        e.printStackTrace();
    }
}

private void loadRootFolder() {
    try {
        final BoxIteratorItems boxIteratorItems = mBoxApiFolder.getItemsRequest(BoxConstants.ROOT_FOLDER_ID).send();
        for (int i = 0; i < boxIteratorItems.getEntries().size(); i++) {
            Log.d(TAG, boxIteratorItems.getEntries().get(i).getName());
        }
    } catch (BoxException boxException) {
        boxException.printStackTrace
    }
}

static class MyProvider implements BoxAuthentication.AuthenticationRefreshProvider, Serializable {
    @Override
    public BoxAuthentication.BoxAuthenticationInfo refreshAuthenticationInfo(BoxAuthentication.BoxAuthenticationInfo info) throws BoxException {
        BoxAuthentication.BoxAuthenticationInfo refreshInfo = new BoxAuthentication.BoxAuthenticationInfo(info.toJsonObject());
        refreshInfo.setAccessToken(ACCESS_TOKEN);
        refreshInfo.setRefreshToken(REFRESH_TOKEN);
        return refreshInfo;
    }

    @Override
    public boolean launchAuthUi(String userId, BoxSession session) {
        return true;
    }
}

}

Hope you can get well with the development of iOS sdk; I would be much appreciated if you or your team have some little time to help me or light me even just a little bit.

Oliver

nidoran commented 4 years ago

Hi @ohs0612 ,

In your MyProvider class, do you have custom logic beyond what you've posted for the implementation of refreshAuthenticationInfo(BoxAuthentication.BoxAuthenticationInfo info). Access tokens expire, so they need to be refreshed, and if your app chooses to handle generating access tokens itself, it will also need to handle refreshing them. This logic would go into that method override. This method should automatically be called when the current access token expires.

Does this help you any?

ohs0612 commented 4 years ago

Hello Nidoran, So, you mean that since MyProvider.refreshAuthenticationInfo would be automatically called as long as the access token expires, I need to generate my new valid access token again by myself, right? I am wondering that except for the default authentication process, are there some methods from the current box android sdk which gets the new access token? I thought this:

mBoxSession = mBoxSession.refresh().get();

would do that, but maybe I am wrong?

Yes, of course, it helps me clarifying my concepts a lot! Thank you!!

nidoran commented 4 years ago

Yes, you will need to generate a new valid access token by yourself in MyProvider.refreshAuthenticationInfo. After that, your BoxSession's internal auth info that wraps an access token should be updated, and further API calls should not return 401.

ohs0612 commented 4 years ago

OK, I see; I'll modify my program into that way! Thank you, Nidoran!