Closed thihaaung6245 closed 8 years ago
Thanks for letting me know. I'll look into it as soon as I can.
I'm still looking into the issue, but the access_token
does expire after 1 hour, so if you need to access user resources then you must have a non-expired access_token
, if I'm not mistaking.
Report to the issue.Here is the log that i tested on my iPhone 6 : iOS 9.3.1
June 2 2016 10:34 AM : INSTALL 11:34 AM : Refresh(Success,return new accesstoken) 12:41 PM : Refresh(Success,return new accesstoken) 1:45 PM : Refresh(Success,return new accesstoken) 2:45 PM : Refresh(Success,return new accesstoken) 4:00 PM : Refresh(Success,return new accesstoken) 5:00 PM : Refresh(Success,return new accesstoken)
June 3 2016 11:10 AM : Refresh(Success,return new accesstoken) 12:32 PM : Refresh(Success,return new accesstoken) 2:37 PM : Refresh(Success,return new accesstoken) 4:45 PM : Log Out (show me "AccessToken Not Found") So,Can’t Log Out (didn’t return any error,I think its stucking at the SDK somewhere else and didn't return me any error from Error response or completion handler.So,I am stucking at the middle)
6:00 PM : I did clear the app from memory and open again,it do refresh and show me this on console RefreshToken not found Refresh error=Optional(Error Domain=TDConnectIosSdk.OAuth2Error Code=0 "(null)")
Looks like the access token did clear itself at some condition or the refresh token.I think may be you need to check AccessTokenExpireDate or RefreshTokenExpireDate.I am trying my best to help you out solve this case.Hope this help.
That issue also happen when user didn't refresh the app for long time...
Are you getting this when you sign out?
Signing out… response=Optional() error=nil AccessToken not found
Is the AccessToken not found
at the end here the problem?
Currently the flow works like this when you sign out:
Sign out
oauth2Module
in SignedInViewController
revokes the access of the tokens.nil
.self.dismissViewControllerAnimated
SignedInViewController
is then dismissed and the SignInViewController
starts appearing.viewDidAppear
method is called in SignInViewController
.if oauth2Module!.isAuthorized()
oauth2Module.isAuthorized()
is -> return self.oauth2Session.accessToken != nil && self.oauth2Session.tokenIsNotExpired()
self.oauth2Session.accessToken
here the console will print AccessToken not found
if the accessToken
is nil
.So every time isAuthorized()
is called when the accessToken
is nil
the console will print AccessToken not found
. See line 144 and line 166 in TrustedPersistantOAuth2Session.swift
.
I understand if it looks like very much like an error. It's a bit misleading. Is that the problem?
This log appear when I log out after I getting refresh error
RefreshToken not found
Refresh error=Optional(Error Domain=TDConnectIosSdk.OAuth2Error Code=0 "(null)")
Signing Out
AccessToken not found
I can manage the log out process.But, we have to do something with refreshing token error.
Here is my working flow :
We have middle-ware server that was working with every telenor services which also include Connect Integration.
1.Login > went to connect login web view > get access token> save the token in my keychain (because i don't know how to get the access token from the Connect SDK offline.)
2.When the token i save in keychain expire in 1 hr or every time I request to that middle-ware server with expire access token,it return Error Code which was "Access Token was Expired"
3.Then I refresh token using you code,
let config = TelenorConnectConfig(clientId: "tnmm-mytelenorapp-ios",
redirectUrl: "tnmm-mytelenorapp-ios://connect/oauth2callback",
useStaging: connect_server_states,
scopes: ["profile", "openid", "email","phone"],
accountId: "tnmm-mytelenorapp-ios")
oauth2Module = AccountManager.getAccountByConfig(config) ?? AccountManager.addAccount(self.config, moduleClass: TelenorConnectOAuth2Module.self)
self.oauth2Module?.refreshAccessToken({(accessToken:AnyObject?, error : NSError?)->Void in
dispatch_async(dispatch_get_main_queue(), {
self.dismissViewControllerAnimated(true){
guard let accessToken = accessToken else {
print("Refresh error=\(error)")
self.showNotifyAlert("Refresh", message: (error?.localizedDescription)!)
return
}
// update the updated token in my keychain
self.configurationUtil.save("Token", value: String(accessToken))
// then call remain web service when getting access token back.
}
})
})
Because my middle-ware server return result code when access token expire.I didn't check this code every time i refresh token.
guard let oauth2Module = self.oauth2Module else {
return
}
if oauth2Module.isAuthorized(){
}
Then after using server hours and do several refresh
RefreshToken not found
Refresh error=Optional(Error Domain=TDConnectIosSdk.OAuth2Error Code=0 "The operation couldn’t be completed. (TDConnectIosSdk.OAuth2Error error 0.)")
RefreshToken not found
Refresh error=Optional(Error Domain=TDConnectIosSdk.OAuth2Error Code=0 "(null)")
These above error happened which is I can't refresh token after getting such error.Log Out operation also failed too after getting such error.
I think you need to check this code.
Looks like you clear refresh token automatically on the client.So,if the refresh token not found return me the above error I posted.I think you need to check something about refreshTokenExpireDate.
Hope this help.
Ok. First thing. You don't have to manually save any tokens when refreshing or requsting tokens. When you're using a TrustedPersistantOAuth2Session
the tokens will be saved in KeyChain for you. See the highlighted line:
This will call self.keychain.save(...
->
Regarding the highlighted lines here:
You must have a refreshToken
to be able to refresh the accessToken
. That is why there is a guard there. If there is no refreshToken
an error has occurred. Are you using TrustedPersistantOAuth2Session
or UntrustedMemoryOAuth2Session
?
We have middle-ware server that was working with every telenor services which also include Connect Integration.
I haven't heard of this middle-ware server before. What does it do? I will ask around if anyone else knows anything about the setup you have, but any more information you can give me would be helpful.
I got 2 questions to ask :
TrustedPersistantOAuth2Session
or UntrustedMemoryOAuth2Session
? because I just call oauth2Module.refreshAccessToken
when I need to refresh token.This is how we do about middle-ware server
Client <-> Middle-ware Server (TopUp,Check Connect Access Token,Other services) <-> Telenor Server
Before we do anything else with the Telenor server it reach to Middle-ware sever first.So,lets talk about
When time that we need to refresh?Here is my working flow of middle ware server and me.
1.Client <-> Request Some Service -> Middle Ware (Check Token [The Access Token which got from Connect] with Telenor Connet Server ) <-> Connect (Check if expire or not)
2.Assume it was expire.
3.Connect <-> Return token was expire <-> Middle-ware (got the response from Connect which was expire token)
4.Middle-ware <-> Send Session Expire [Result Code] <-> Client
Then client read the result code and refresh the app using your oauth2Module.refreshAccessToken()
Calling requestAccess()
will always give you a valid accessToken
.
accessToken
for you and give you that.accessToken
or a refreshToken
(if a user is not signed in) then it will sign in the user and then give you the accessToken
.You should never need to manually call refreshAccessToken
. Just call requestAccess()
when you want the accessToken
.
oauth2Module!.requestAccess { (accessToken: AnyObject?, error: NSError?) in
print("accessToken is -> \(accessToken)")
}
produces accessToken is -> Optional(rk9p2jpjgp37llCTn1jyRHehOht)
If you do not specify a OAuth2Session
to the init
function of OAuth2Module
it will use TrustedPersistantOAuth2Session
.
So,looks like i have to use requestAccess instead of refreshAccessToken when i try to refresh token.So,I need to know that state :
If I happen that,will it reach to ConnectWebView or will it automatically sign in without reaching ConnectWebView and give me access token i need?
If no user is signed in it will have to open a web view to authenticate and authorize the user. Specifically it will call requestAuthorizationCode(…
, and on the last line here it will present a web view controller ->
Hmmm,I see.Now,let me try with requestAccess() starting for now.If it didn't work out and happen error like this :
RefreshToken not found
Refresh error=Optional(Error Domain=TDConnectIosSdk.OAuth2Error Code=0 "(null)")
I will let you know.Thanks for the support.
Ok. Let me know what happens 👍
Calling requestAccess() will always give you a valid accessToken.
- If it is not expired, you will get the one saved in keychain.
- If it is expired, but you have a refresh token, it will refresh the accessToken for you and give you that.
- If you don't have an accessToken or a refreshToken (if a user is not signed in) then it will sign in the user and then give you the accessToken.
I am having strange situation with third condition.I am sign in to connect of course.But,looks like my accessToken and refreshToken expired after I haven't used the app for a period of time,like 2 days.
So,it reached the third condition that you mentioned but I am sign in user who didn't use the app for 2 days.But,strange behavior is,I have to login again for two times.
When the third condition reach,it bring me connect login page. After i clicked allow all permission,It dismissed web view controller(SFSafariViewController) and appeared again.So,I have to login two times.Then I got the access token,Can you check it whats wrong?
Yes, I will look into it.
If u need some log,I will post here when I have it.
But,strange behavior is,I have to login again for two times.
I made a new release: 0.6.7. I think your problem will go away by using this latest version. Consider making the same changes as I made in the SignInViewController.
So,it reached the third condition that you mentioned but I am sign in user who didn't use the app for 2 days.
It is very strange that you don't have a valid Refresh Token after only 2 days. Refresh Tokens have an expiration date in the order of months. Are you refreshing directly or is the middleware server doing this?
No,I am refreshing directly.Middle-ware only check accesstoken and see if valid or not. If it is not valid,it return response string "Token Expire" to my app and I do refreshing directly with Telenor Connect using your sdk method "requestAccess"
Did the latest version help with either of the two issues?
Still not having that issue again....Besides its rare.I will let you know when that happen again.
Since I have updated the latest update which handle refresh token error,it worked for a moment.But,I am still experiencing those error logs at console
iPhone 4, iOS : 8
iPhone 6, iOS : 9.2.1
Every 1 hr,the access token is expire and it request new access token with refresh token.So,there might be something wrong with refresh token on SDK or the Connect Server Side which I still didn't figure it out for sure.Or may be the Refresh Token ExpireDate.I am collecting my own log time that I refresh token.I will post that log tomorrow.I mean which time I refresh token per day.
All my telenor services are working with Connect Access Token,So,If I don't have Access token,I can't do anything or can't request any services.As well as refreshing token,log in,revoke token from Connect.
Would you please take a look at this problem?
With Regards, Telenor Self-Care App iOS Developer.