Does scope have to be at the end of the authorize request?


#1

I’ve been transitioning a python chat bot / flask app away from the community key generator for the past week and it’s been one big headache. None of the oauth helper libraries seem to play nice with twitch.

I finally got the oauth flow going without any error by forgoing any helper module just doing a raw redirect with everything just written straight into a string then readign the code and doing a post request to get the actual key.

It was working without any errors but would refuse to give me any scopes back. I was using ‘+’ for spaces and I tried encoding the url and not encoding the url diffrent scopes, 1 scope, nothing worked.

I finally just put the &scope= at the very end of the string after the state and it suddenly started working. any insights in this? I can post the code but honestly I need to rewrite it so it’s not a giant example of bad coding practices.


#2

You basically sound like a similar problem as described here.

You didn’t URLencode your redirect_uri so you accidentally merged your redirect URL with the rest of the arguments. Or some other odd combination of fields resulting in things not parsing as expected twitch side.

Scope doesn’t need to be at the end, the argument order doesn’t matter.

I’d know for sure if you provide the actual URLs you have tried/generated


#3

Thanks for the reply, just to follow up on this if anyone has the same problem.

In Python 3, I was using the default parsing in urllib.parse which was not encoding the parameters properly, you need to use urllib.parse.quote_plus with the following safe chars “?:=&/”.

here is the proper encoding using urllib as a function within my code. note that the rederect_uri comment is for flask apps only.

    def redirect_url(self,redirect_uri, scope):
        # make sure the redirect uri is stated for external access url_for(...,_external=true)
        # scopes can be a string or a list of strings
        auth_url='https://id.twitch.tv/oauth2/authorize'
        # replace the self.client_id with your client id
        client_arg=f'?client_id={self._client_id}'
        redirect_url=f'&redirect_uri={redirect_uri}'
        response_type='&response_type=code'
        state=f'&state={self._state}'
        if type(scope) == list:
            scope_args='&scope=' + ' '.join(scope)
        elif type(scope) == str:
            scope_args='&scope='+scope
        full_args=client_arg+redirect_url+response_type+state+scope_args
        encoded_url=auth_url + urllib.parse.quote_plus(full_args,safe='?:=&/')
        return encoded_url