1
Solved

oauth2: HTTP Auth method oauth2 does not replace the last refresh_token with the new refresh_token

When the HTTP Auth action using oauth2 uses a previously stored refresh_token to refresh both the access and refresh tokens, the auth server returns new access and refresh tokens, but tasker is not replacing the old refresh_token with the new refresh_token. Tasker continues to use the older refresh_token, which technically has not expired, but the server side deletes the older refresh_token since the server knows it just issued a new refresh_token.

When tasker subsequently tries to refresh the access token, it uses the older, no longer valid, refresh token and, of course, authentication fails.

The oauth2 spec is long and complex, so I am not claiming tasker is wrong since that older refresh_token technically hasn't expired when the problem occurs, but I have observed that every other client implementation of oauth2 I've encountered does indeed start using the new refresh_token so it would be helpful if tasker did as well.

Tasker version is 5.10.1

4 replies

BB

I've sent you an email with a full sample project and the other info needed to use it to reproduce the problem. I received your "away" auto-response, so have a nice holiday!

BB

If you can provide a way for me to contact you privately, I can set up a test account on the server for you and I'll provide updated tasks with that configuration. It may be the weekend before I can reply with that info, however.

Sure! Please contact me at the email available here: https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm

Thank you very much in advance!

BB

Here you go.  These two tasks will recreate the problem for me. I did instrument the auth server to keep track of refresh_tokens issued to this client_id and phone IP address and I could clearly see tasker using the original refresh_token after the second refresh_token was issued. Simply adding auth server code to to preserve and lengthen the expiration of the original auth_token for this client_id is the workaround I am using now, and all is reliable.

The only other thing I can think of as being relevant to you is that during development I used multiple OAuth2 tasks within the same project and all directed at the same auth server. This didn't work reliably for reasons I didn't debug because I discovered I could call the same OAuth2 task like a function, as I did below, before every HTTP request to the server. Given you think you've implemented what I described as the expected behavior, is there some internal state that is maybe still trying to track multiple interactions with the same auth server and the new refresh_token is just going somewhere "random?"   

<TaskerData sr="" dvi="1" tv="5.10.1">
        <Task sr="task36">
                <cdate>1606492515635</cdate>
                <edate>1607945360086</edate>
                <id>36</id>
                <nme>HTTPS api.XXXXXX.com OAuth2</nme>
                <pri>100</pri>
                <Action sr="act0" ve="7">
                        <code>351</code>
                        <Bundle sr="arg0">
                                <Vals sr="val">
                                        <net.dinglisch.android.tasker.RELEVANT_VARIABLES>&lt;StringArray sr=""&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0&gt;%http_auth_headers
Headers
Use this in the HTTP Request action in the 'Headers' field to authenticate the request&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0&gt;&lt;/StringArray&gt;</net.dinglisch.android.tasker.RELEVANT_VARIABLES>
                                        <net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>
                                </Vals>
                        </Bundle>
                        <Int sr="arg1" val="0"/>
                        <Str sr="arg10" ve="3"/>
                        <Str sr="arg2" ve="3">tasker</Str>
                        <Str sr="arg3" ve="3">MY_SECRET</Str>
                        <Str sr="arg4" ve="3">https://api.XXXXXX.com/YYYY/oauth2/authorize?redirect_uri=https%3A%2F%2Fapi.XXXXXX.com%2Fopen%2Ftasker%2Fauth.html</Str>
                        <Str sr="arg5" ve="3">https://api.XXXXXX.com/YYYY/oauth2/token</Str>
                        <Str sr="arg6" ve="3"/>
                        <Int sr="arg7" val="0"/>
                        <Int sr="arg8" val="30"/>
                        <Str sr="arg9" ve="3"/>
                </Action>
                <Action sr="act1" ve="7">
                        <code>547</code>
                        <Str sr="arg0" ve="3">%HTTP_AUTH_HEADERS</Str>
                        <Str sr="arg1" ve="3">%http_auth_headers</Str>
                        <Int sr="arg2" val="0"/>
                        <Int sr="arg3" val="0"/>
                        <Int sr="arg4" val="0"/>
                        <Int sr="arg5" val="3"/>
                </Action>
                <Action sr="act2" ve="7">
                        <code>547</code>
                        <Str sr="arg0" ve="3">%SSID</Str>
                        <Str sr="arg1" ve="3">%WIFII</Str>
                        <Int sr="arg2" val="0"/>
                        <Int sr="arg3" val="0"/>
                        <Int sr="arg4" val="0"/>
                        <Int sr="arg5" val="3"/>
                </Action>
                <Action sr="act3" ve="7">
                        <code>590</code>
                        <Str sr="arg0" ve="3">%SSID</Str>
                        <Str sr="arg1" ve="3">"</Str>
                        <Int sr="arg2" val="0"/>
                </Action>
                <Action sr="act4" ve="7">
                        <code>547</code>
                        <Str sr="arg0" ve="3">%SSID2</Str>
                        <Str sr="arg1" ve="3">CELLULAR_DATA</Str>
                        <Int sr="arg2" val="0"/>
                        <Int sr="arg3" val="0"/>
                        <Int sr="arg4" val="0"/>
                        <Int sr="arg5" val="3"/>
                        <ConditionList sr="if">
                                <Condition sr="c0" ve="3">
                                        <lhs>%SSID2</lhs>
                                        <op>13</op>
                                        <rhs></rhs>
                                </Condition>
                        </ConditionList>
                </Action>
        </Task>
</TaskerData>
<TaskerData sr="" dvi="1" tv="5.10.1">
        <Task sr="task20">
                <cdate>1606492515635</cdate>
                <edate>1607858768105</edate>
                <id>20</id>
                <nme>HTTPS Request - For Testing</nme>
                <pri>100</pri>
                <Action sr="act0" ve="7">
                        <code>130</code>
                        <Str sr="arg0" ve="3">HTTPS api.XXXXXX.com OAuth2</Str>
                        <Int sr="arg1">
                                <var>%priority</var>
                        </Int>
                        <Str sr="arg2" ve="3"/>
                        <Str sr="arg3" ve="3"/>
                        <Str sr="arg4" ve="3"/>
                        <Int sr="arg5" val="0"/>
                        <Int sr="arg6" val="0"/>
                        <Str sr="arg7" ve="3"/>
                        <Int sr="arg8" val="0"/>
                        <Int sr="arg9" val="0"/>
                </Action>
                <Action sr="act1" ve="7">
                        <code>339</code>
                        <Bundle sr="arg0">
                                <Vals sr="val">
                                        <net.dinglisch.android.tasker.RELEVANT_VARIABLES>&lt;StringArray sr=""&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0&gt;%http_data
Data
Data that the server responded from the HTTP request.&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1&gt;%http_file_output
File Output
Will always contain the file's full path even if you specified a directory as the File to save.&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2&gt;%http_response_code
Response Code
The HTTP Code the server responded&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3&gt;%http_cookies
Cookies
The cookies the server sent in the response in the Cookie:COOKIE_VALUE format. You can use this directly in the 'Headers' field of the HTTP Request action&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES4&gt;%http_headers()
Response Headers
The HTTP Headers the server sent in the response. Each header is in the 'key:value' format&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES4&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES5&gt;%http_response_length
Response Length
The size of the response in bytes&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES5&gt;&lt;/StringArray&gt;</net.dinglisch.android.tasker.RELEVANT_VARIABLES>
                                        <net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>
                                </Vals>
                        </Bundle>
                        <Int sr="arg1" val="0"/>
                        <Int sr="arg10" val="0"/>
                        <Int sr="arg11" val="0"/>
                        <Str sr="arg2" ve="3">https://api.XXXXXX.com/YYYY/tasker</Str>
                        <Str sr="arg3" ve="3">%HTTP_AUTH_HEADERS</Str>
                        <Str sr="arg4" ve="3">go:ping
batt:%BATT
bt:%BLUE
cname:%CNAME
cnam:%CNUM
cdate:%CDATE
ctime:%CTIME
cellid:%CELLID
cellsig:%CELLSIG
loc:%LOC
locacc:%LOCACC
localt:%LOCALT
locspd:%LOCSPD
ssid:%SSID2
smsrf:%SMSRF
smsrn:%SMSRN
smsrb:%SMSRB
mmsrs:%MMSRS
smsrd:%SMSRD
smsrt:%SMSRT</Str>
                        <Str sr="arg5" ve="3"/>
                        <Str sr="arg6" ve="3"/>
                        <Str sr="arg7" ve="3"/>
                        <Int sr="arg8" val="30"/>
                        <Int sr="arg9" val="0"/>
                </Action>
        </Task>
</TaskerData>

Thank you! :) You don't happen to have some throwaway real info that I can use to test with a server do you?

Hi. This should already be happening. Can you please post an example of a task where you can see this behaviour? Thanks!

Topic is closed for comments