pennersr / django-allauth

Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication.
https://allauth.org
MIT License
9.51k stars 3.03k forks source link

Telegram provider login url does not work #2629

Closed ak4zh closed 1 year ago

ak4zh commented 4 years ago

Telegram provider has two issues:

1) Login url does not work. <a href="{% provider_login_url "telegram" %}">Telegram</a> results in no # link to same page.

The login functionality does work if you use the telegram login widget directly from Telegram website

2) Connecting a telegram account on existing account does not work. Attempt with provider_login_url: <a href="{% provider_login_url "telegram" process="connect"%}">Telegram</a>

I also tried setting data-auth-url as /accounts/telegram/login/?process=connect in the official widget. Both method fails.

alsonpr commented 3 years ago

hi @Ak4zh , I am facing the same issue. Did you find any solution? Any help would be appreciated. Thanks

dkarelov commented 3 years ago

Same here. Docs should be expanded.

crypto-rizzo commented 3 years ago

@pennersr am I missing something here? I know Telegram has their own login widget, but docs do seem a bit sparse

https://github.com/pennersr/django-allauth/blob/c50a30acc0e4553297b0ddb697d55a290ed6d038/allauth/socialaccount/providers/telegram/provider.py#L14

JuMasta commented 3 years ago

Hello everyone, i've resolved this issue by these steps:

  1. Created bot and set domain 127.0.0.1 (you might have another)
  2. Created widget here https://core.telegram.org/widgets/login with redirect to http://127.0.0.1:80/accounts/telegram/login/ (very important use 80 port or button won't work )
  3. Copied field Embed Code into my html page
  4. set value for token in setting.py (SOCIALACCOUNT_PROVIDERS = { 'telegram': { 'TOKEN': 'your tokken' } })
tarapiygin commented 2 years ago

I also encountered an authorization error in telegram. After looking at the source code, I found out that the problem is that expected_hash and hash (from your token) do not match.

def telegram_login(request):
    provider = providers.registry.by_id(TelegramProvider.id, request)
    data = dict(request.GET.items())
    hash = data.pop("hash")
    payload = "\n".join(sorted(["{}={}".format(k, v) for k, v in data.items()]))
    token = provider.get_settings()["TOKEN"]
    token_sha256 = hashlib.sha256(token.encode()).digest()
    expected_hash = hmac.new(token_sha256, payload.encode(), hashlib.sha256).hexdigest()
    auth_date = int(data.pop("auth_date"))
    if hash != expected_hash or time.time() - auth_date > 30: #problem here
        return render_authentication_error(
            request, provider_id=provider.id, extra_context={"response": data}
        )

    login = provider.sociallogin_from_response(request, data)
    return complete_social_login(request, login)

The problem lies in /telegram/views.py or in telegram itself...

pennersr commented 1 year ago

Fixed via 89944bc2

arnoan commented 1 year ago

Hi there,

I am not sure if it is bad practice in GitHub to comment on a closed Issue, but I have been (unsuccessfully) trying to get the django-allauth Telegram provider to work for multiple days now and this GH conversation is the closest to a glimmer of hope for a possible solution I could find.

I just wanted to ask: @ak4zh , @JuMasta are any of you still using Django AllAuth in conjunction with Telegram in one of your projects and could someone confirm that it is indeed possible to get this setup working at this current moment in time?

I have tried everything I could think of. The official social provider settings from the AllAuth docs, the setup using a TOKEN instead, proposed by @JuMasta , Django Bot and corresponding domain are correctly configured. I tried different re-direct URLs (with explicit port, without port, 80, 443) running it "locally" via Ngrok (Telegram these days does not seem to support 127.0.0.1 as a domain anymore), running the full setup on a Render.com web service.. I tried it both without "django.contrib.sites" and SITE_ID = 1 (which currently is not part of the AllAuth Installation documentation anymore, but some older tutorials still reference it..), as well as with these settings. I also tried manually adding the provider via the Django Admin, to no avail. I am out of ideas what else I could try.

Whenever I attempt to "login" via Telegram, I run into the following error:

image

And my logs show: [10/Sep/2023 17:42:47] "GET /accounts/login/ HTTP/1.1" 200 2973 [10/Sep/2023 17:42:50] "GET /accounts/login/ HTTP/1.1" 200 2973 [10/Sep/2023 17:42:52] "GET /accounts/telegram/login/?process=login HTTP/1.1" 302 0

I would be extremely grateful for any pointers.. And - to add some more weight - I hereby openly pledge that if someone can help me figure out how to make the telegram provider work, I promise I will write a documentation post or blog article to describe the process in detail and maybe help some other people.

I am happy to provide whatever further information might be useful. I also set up a dedicated troubleshoot django project and web service on Render for experimentation on this, so I can quickly test any combination of settings in a live setting..

Many thanks in advance, Arno

pennersr commented 1 year ago

@arnoan Those logs are likely incomplete, as I would expect that the callback URL would also be in that list, how else can the "Social Network Login Failure" appear? In any case, that error is triggered here:

https://github.com/pennersr/django-allauth/blob/main/allauth/socialaccount/providers/telegram/views.py#L67

So I suggest you put a breakpoint in this post() method and step through the code to see what is going on in your case.

arnoan commented 1 year ago

@pennersr Thank you for the lightning fast response. I am very impressed!! Your are correct, the logs I pasted got truncated. I just ran it again and here's the full logs:

Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. [10/Sep/2023 18:58:00] "GET / HTTP/1.1" 200 693 [10/Sep/2023 18:58:04] "GET /accounts/login/ HTTP/1.1" 200 2992 [10/Sep/2023 18:58:07] "GET /accounts/telegram/login/?process=login HTTP/1.1" 302 0 [10/Sep/2023 18:58:08] "GET /accounts/telegram/login/callback/?process=login HTTP/1.1" 200 118 [10/Sep/2023 18:58:08] "POST /accounts/telegram/login/callback/?process=login HTTP/1.1" 200 673 ^C%

Minimal setup to focus in on the error: 1) Starting the server (local in this case for debugging + ngrok to test with a valid domain name for the telegram bot) 2) open the page into the home view 3) go to the login page 4) press the Telegram Login button 5) Receiving 200 status codes for the callback but displaying "Social Network Failure"

Will attempt breakpoint and stepping through the post() method now, though I am not exactly sure yet what irregularities I am looking for. Will go for a hunt and report back. (I am confident with Python yet quite new in the WebDev/Django world. )

arnoan commented 1 year ago

Ok, here's what I found:

My assumption is that this should be populated from the SOCIALACCOUNT_PROVIDERS section in settings.py.
Here's mine (with both client_id and secret, as specified in the official docs, as well as TOKEN, as suggested by another user here in this issue): image

For context, here also the debugging screen of the relevant code section from PyCharm (with potentially sensitive information obscured): image

pennersr commented 1 year ago

The app gets populated either from the SocialApp data stored in the database, or, from the settings. So, you might want to check provider.app.pk -- if the app has a primary key, it is a record residing in the database, meaning, it does not use your settings. Also, it might just be the case that TELEGRAM_BOT_TOKEN = "" in your case..

arnoan commented 1 year ago

Thank you for the further context, it really is highly appreciated! And my mental model of what is going on in the background is growing.. I identified the root cause and it eventually was something embarrassingly trivial. I did have a typo in the code for loading the token environment variable and thus it resorted to the default, an empty string..

I had omitted to include a test-case to ensure that the variable is indeed "truthy".. Either way, THANK YOU immensely for the support (and the fantastic package!) and I am grateful for the additional knowledge acquired along the way.. And I am beyond happy, that it is now running as intended for me.

As to my pledge -> I am herewith committed to document the process required to get Django + django-allauth with the Telegram Provider fully up and running. In the end it was a trivial mistake that tripped me up. But the whole process leading up to that point - at least for me - was far from trivial. So I feel the world, my future self included 😄, could benefit from some extra documentation. I'll share a link here, once ready.

Thanks again and have a great night! 🙏