Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 403 authorization errors #128

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open

Fix 403 authorization errors #128

wants to merge 10 commits into from

Conversation

Teuns
Copy link

@Teuns Teuns commented Nov 20, 2024

Probably related: #127

For some reason the authentication process returns 403 errors all of a sudden. I think this is due to CloudFlare blocking the requests automatically. This branch solves it by using urllib instead of requests in the specific faulty requests, as pointed out in a StackOverflow post](https://stackoverflow.com/a/74674276).

kobodl/kobo.py Outdated
Comment on lines 532 to 535
def get_cookie_value(cookie_name):
if cookie_name in cookie:
return cookie[cookie_name].value
return None
Copy link

@lubomir-brindza lubomir-brindza Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This closure is never called; did you mean to leave this in here?

e: Looking at this some more, there's some redundant code here; this whole block (529-543) seems like it's a leftover and no longer necessary

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! That definitely shouldn't be in here. I'll delete it

@lubomir-brindza
Copy link

lubomir-brindza commented Nov 21, 2024

I can confirm that this PR does fix the login issue for me, nice work :)

@subdavis apologies for barging in here, I just know from the related issues that you're not affected / able to reproduce this

@@ -166,7 +184,7 @@ def __GetExtraLoginParameters(self) -> Tuple[str, str, str]:
)
requestVerificationToken = html.unescape(match.group(1))

return koboSignInUrl, workflowId, requestVerificationToken
return koboSignInUrl, workflowId, requestVerificationToken, authCookie

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to update the return type for __GetExtraLoginParameters to Tuple[str, str, str, str]

@bybpow
Copy link

bybpow commented Nov 21, 2024

Please merge this soon. I reseted my account and now I can't add a user or download. Thanks for your work.

@chewi
Copy link

chewi commented Nov 21, 2024

This doesn't seem to fix it for me, but I'm seeing it on the download request.

requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://storedownloads.kobo.com/download?downloadToken=XXXXXXXX

@subdavis
Copy link
Owner

Thanks everyone for your involvement in this fix. I'll get this merged and released later this evening.

@rainrdx
Copy link

rainrdx commented Nov 26, 2024

This doesn't seem to fix it for me, but I'm seeing it on the download request.

requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://storedownloads.kobo.com/download?downloadToken=XXXXXXXX

Seems to still get 403 Forbidden on my end sadly

@Teuns
Copy link
Author

Teuns commented Nov 27, 2024

This doesn't seem to fix it for me, but I'm seeing it on the download request.

requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://storedownloads.kobo.com/download?downloadToken=XXXXXXXX

Seems to still get 403 Forbidden on my end sadly

Hmm, strange. I suppose it could be fixed by replacing that request with urllib too. I'll take a look at it. What OS are you running it on?

@rainrdx
Copy link

rainrdx commented Nov 27, 2024

This doesn't seem to fix it for me, but I'm seeing it on the download request.

requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://storedownloads.kobo.com/download?downloadToken=XXXXXXXX

Seems to still get 403 Forbidden on my end sadly

Hmm, strange. I suppose it could be fixed by replacing that request with urllib too. I'll take a look at it. What OS are you running it on?

I’m running it on macOS but I’m on vacation so I’m from weird IP. Maybe it’s IP related and I will try again once I’m back home with residential IP in the U.S.

@chewi
Copy link

chewi commented Nov 27, 2024

Gentoo here, running at home in Scotland on a static IP. I don't think it's the IP though. I know that CloudFlare will block for all sorts of reasons. Lack of a User-Agent string is just one. I suspect urllib could be configured to be acceptable, but it's hard to know exactly what CloudFlare doesn't like about it.

@Teuns
Copy link
Author

Teuns commented Nov 29, 2024

I've just pushed some commits that introduces a (WIP) request wrapper that revolves around urllib and replaced all requests with it. I successfully authenticated and downloaded an ebook with it using a VPN. The code obviously needs to be refacatored and tested properly but feel free to test it let me know if it works.

@rainrdx
Copy link

rainrdx commented Nov 29, 2024

Thank you so much for working on this. I tried two ips, my ip on a cruise ship and another ip on azure, both shows 403 forbidden when requesting
Making request to https://authorize.kobo.com/signin?returnUrl

I feel this is more likely an ip issue with where I am. I will try again next week when I am back.

@rainrdx
Copy link

rainrdx commented Nov 29, 2024

and I tried so many VPNs all failed. This is so weird. Again thank you for working on this weird issue

@bybpow
Copy link

bybpow commented Nov 29, 2024

This works for me! Thanks for your contribution.

@chewi
Copy link

chewi commented Nov 29, 2024

No luck here, although the error is different.

Making request to https://storeapi.kobo.com/v1/initialization
Making request to https://storeapi.kobo.com/v1/library/sync
Making request to https://storeapi.kobo.com/v1/library/sync
Making request to https://storeapi.kobo.com/v1/library/sync
Skipping subscribtion entity
Skipping subscribtion entity
Downloading e0a9b304-83f1-4a7d-a170-4aee884d35c2 to /tmp/audiobooks/Adrian Tchaikovsky - Eyes of the Void e0a9b304
Making request to https://storedownloads.kobo.com/download?downloadToken=XXXXXXXX
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/decorators.py", line 33, in new_func
    return f(get_current_context().obj, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/commands/book.py", line 83, in get
    actions.GetBookOrBooks(usercls, output_dir, formatStr=format_str, productId=pid)
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/actions.py", line 231, in GetBookOrBooks
    kobo.Download(bookMetadata, book_type == BookType.AUDIOBOOK, outputFilePath)
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/kobo.py", line 428, in Download
    self.__DownloadAudiobook(downloadUrl, outputPath)
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/kobo.py", line 347, in __DownloadAudiobook
    request = Request(url)
              ^^^^^^^^^^^^
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/kobo.py", line 59, in __init__
    self.request = urllib.request.Request(url, data=data, headers=headers)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/urllib/request.py", line 324, in __init__
    for key, value in headers.items():
                      ^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'items'

Admittedly I've tweaked it to use Python 3.12, 3.10 is too old for my system, but it did work fine with 3.12 before.

@Teuns
Copy link
Author

Teuns commented Nov 30, 2024

No luck here, although the error is different.

Making request to https://storeapi.kobo.com/v1/initialization
Making request to https://storeapi.kobo.com/v1/library/sync
Making request to https://storeapi.kobo.com/v1/library/sync
Making request to https://storeapi.kobo.com/v1/library/sync
Skipping subscribtion entity
Skipping subscribtion entity
Downloading e0a9b304-83f1-4a7d-a170-4aee884d35c2 to /tmp/audiobooks/Adrian Tchaikovsky - Eyes of the Void e0a9b304
Making request to https://storedownloads.kobo.com/download?downloadToken=XXXXXXXX
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/decorators.py", line 33, in new_func
    return f(get_current_context().obj, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/commands/book.py", line 83, in get
    actions.GetBookOrBooks(usercls, output_dir, formatStr=format_str, productId=pid)
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/actions.py", line 231, in GetBookOrBooks
    kobo.Download(bookMetadata, book_type == BookType.AUDIOBOOK, outputFilePath)
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/kobo.py", line 428, in Download
    self.__DownloadAudiobook(downloadUrl, outputPath)
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/kobo.py", line 347, in __DownloadAudiobook
    request = Request(url)
              ^^^^^^^^^^^^
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/kobo.py", line 59, in __init__
    self.request = urllib.request.Request(url, data=data, headers=headers)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/urllib/request.py", line 324, in __init__
    for key, value in headers.items():
                      ^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'items'

Admittedly I've tweaked it to use Python 3.12, 3.10 is too old for my system, but it did work fine with 3.12 before.

Seems like urllib doesn't like it when you pass None as the headers value (which is of course not very surprising given the fact that the type is a dictionary). My latest commit should fix it!

@chewi
Copy link

chewi commented Nov 30, 2024

That did the trick. Many thanks.

@bybpow
Copy link

bybpow commented Nov 30, 2024

No luck here, although the error is different.

Making request to https://storeapi.kobo.com/v1/initialization
Making request to https://storeapi.kobo.com/v1/library/sync
Making request to https://storeapi.kobo.com/v1/library/sync
Making request to https://storeapi.kobo.com/v1/library/sync
Skipping subscribtion entity
Skipping subscribtion entity
Downloading e0a9b304-83f1-4a7d-a170-4aee884d35c2 to /tmp/audiobooks/Adrian Tchaikovsky - Eyes of the Void e0a9b304
Making request to https://storedownloads.kobo.com/download?downloadToken=XXXXXXXX
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/.cache/pypoetry/virtualenvs/kobodl-NpcgVQ5e-py3.12/lib/python3.12/site-packages/click/decorators.py", line 33, in new_func
    return f(get_current_context().obj, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/commands/book.py", line 83, in get
    actions.GetBookOrBooks(usercls, output_dir, formatStr=format_str, productId=pid)
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/actions.py", line 231, in GetBookOrBooks
    kobo.Download(bookMetadata, book_type == BookType.AUDIOBOOK, outputFilePath)
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/kobo.py", line 428, in Download
    self.__DownloadAudiobook(downloadUrl, outputPath)
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/kobo.py", line 347, in __DownloadAudiobook
    request = Request(url)
              ^^^^^^^^^^^^
  File "/home/chewi/Projects/kobo-book-downloader/kobodl/kobo.py", line 59, in __init__
    self.request = urllib.request.Request(url, data=data, headers=headers)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/urllib/request.py", line 324, in __init__
    for key, value in headers.items():
                      ^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'items'

Admittedly I've tweaked it to use Python 3.12, 3.10 is too old for my system, but it did work fine with 3.12 before.

Seems like urllib doesn't like it when you pass None as the headers value (which is of course not very surprising given the fact that the type is a dictionary). My latest commit should fix it!

This also happened to me. You also need to add the cloudscrapper patch but this fix works for the login.

@rainrdx
Copy link

rainrdx commented Dec 1, 2024

I just want to share that TnS-hun's recent commits fixed the 403 problem for me
https://github.com/TnS-hun/kobo-book-downloader/commits/master/

@Teuns
Copy link
Author

Teuns commented Dec 1, 2024

I just want to share that TnS-hun's recent commits fixed the 403 problem for me https://github.com/TnS-hun/kobo-book-downloader/commits/master/

Interestingly enough it doesn't work for me:

requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://authorize.kobo.com/signin (...)

Maybe you're using it on an IP address that doesn't get blocked easily by CloudFlare? It used to work weeks before though.

@rainrdx
Copy link

rainrdx commented Dec 1, 2024

I just want to share that TnS-hun's recent commits fixed the 403 problem for me https://github.com/TnS-hun/kobo-book-downloader/commits/master/

Interestingly enough it doesn't work for me:

requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://authorize.kobo.com/signin (...)

Maybe you're using it on an IP address that doesn't get blocked easily by CloudFlare? It used to work weeks before though.

That's really weird. I think I will just stop here as it's really hard to debug this. Cloudflare is just flaky to bypass and I got my tokens. Thank you!

@rainrdx
Copy link

rainrdx commented Dec 1, 2024

Just came back home and with clean ip, everything works with your commits. I guess this was just an ip issue with cloudflare. Thank you!

@rainrdx
Copy link

rainrdx commented Dec 9, 2024

sadly, seems nothing works for me now. My home IP, my office IP, etc. all show up with the 403 forbidden for authorize.kobo.com sigh....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants