Closed gaxweb closed 8 months ago
Ok, it seems the reason is that, if you don't explicitly configure the AdminAuthenticator
options to retry at least once, it won't do it at all and the 10 minute token will simply expire. That should be made more obvious IMHO.
Should have looked into the logs first. Error still occurring.
Can I please get an answer on this:
Does the client not make sure that the access token stays valid?
Do I have to refresh it myself? I can't find an error with the code. It works fine for about 10 Minutes (the default token time limit) and then it throws the error in the title.
The repository methods to fetch data require a Context
object. This object requires an AccessToken
object and this is generated by using the AdminAuthenticator
. That has to be triggered manually.
There is no automatic refresh. Shopware also doesn't provide a refresh token for every grant type. A client credentials authentication token e.g. doesn't contain one.
The AccescToken
class has a isExpired
method which can be used to check if a new token is required. If the token is expired an there is a refresh token, a RefreshTokenGrantType
object can be created to reauthenticate. But this has to be done manually, too.
If the token used in the context object for the request is expired, Shopware will simply return 401 and the SDK will throw that as an exception.
@gaxweb
Do I have to refresh it myself? I can't find an error with the code. It works fine for about 10 Minutes (the default token time limit) and then it throws the error in the title.
With PasswordTypeGrantType, its by default alive for 10 minutes. You need to refresh the token afterward using RefreshTokenGrantType as hint from @SpiGAndromeda If you want a longer duration access token, you can use ClientCredentialsGrantType instead
This is the code I use to refresh a previously retrieved PasswordGrant token:
protected function refresh(int $time){
static $seconds = 0;
if ($seconds === 0 or ($time - $seconds >= 300)) {
$accessToken = $this->adminClient->fetchAccessToken();
$grantType = new RefreshTokenGrantType($accessToken->refreshToken);
$this->adminClient = new AdminAuthenticator($grantType, $this->api_uri, $this->config);
$this->context = new Context($this->api_uri, $accessToken);
$this->syncService = new SyncService($this->context);
$seconds = $time;
}
}
I'm running this once right at the start to retrieve the access token the 1st time, then in various long running methods again.
After a bit more than 10min, I still get 401 errors like "Access token could not be verified"
. Do you see a problem with the way I'm doing it? I'm starting to lose my mind. Is it a problem that I request a new one before the 10 min have passed?
Shopware version 6.5.7.3, SDK version 2.0.0
After looking at a recent pull request, I've reduced it to this:
public function connect(string $api_uri, string $username, string $password): void {
$grantType = new PasswordGrantType($username, $password);
$adminClient = new AdminAuthenticator($grantType, $api_uri, $this->config);
$this->context = new Context($api_uri, $adminClient->fetchAccessToken());
$this->syncService = new SyncService($this->context);
}
protected function refresh(int $time){
if ($this->context->accessToken->isExpired()) {
$grantType = new RefreshTokenGrantType($this->context->accessToken->refreshToken);
$adminClient = new AdminAuthenticator($grantType, $this->context->apiEndpoint, $this->config);
$this->context = new Context($this->context->apiEndpoint, $adminClient->fetchAccessToken());
$this->syncService = new SyncService($this->context);
}
}
Still the same error.
Oh boy… I was using a MediaService which was still trying to use the old Context object after the refresh…
Error code 9, Status 401.
Does the client not make sure that the access token stays valid? It seems like I'm getting a timeout right in the middle of a long running process (after about 623s).
If not, what would be the best practice to keep the token valid and hence the connection alive? Keeping track of the time that has passed seems silly to me.
I'm using the PasswordGrantType.