Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disqus SSO - Not working

I am using Python and Django to log into Disqus. The admins have confirmed that the account has SSO enabled and their debug tools confirm that my login token is correct.. However my config seems to be ignore.. Login buttons are not getting replaced and so on..

Here is an example of the JS Disqus implementation..

var disqus_shortname = 'outfit418alpha';
var disqus_config = function() {
        this.page.remote_auth_s3 = 'eyJ1c2VybmFtZSI6ICJkaXNxdXMiLCAiaWQiOiA1OTEsICJlbWFpbCI6ICJkaXNxdXNAb3V0Zml0NDE4LmNvbSJ9 577222fb9c6d5e03238fb70d29ac1104469e1e85 1390561160';
        this.page.api_key = 'jkNAtL6ivcDNjDBbl9RFMy3prUSypfTto1IRlrsaMFXqFauGQlQQHAwOo8R8bRlG';
        this.sso = {
            url: '/profile/login/',
            logout: '/profile/logout/',
        }
    }

    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
    dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();

Could anyone point me in the direction of where i am going wrong?

like image 915
Lee Avatar asked Jan 24 '14 11:01

Lee


2 Answers

We went through several code implementations on GitHub to integrate Disqus SSO in our Django website. Our requirement was a simple one and we used the following workflow for it:

In disqus.py:

import base64
import hashlib
import hmac
import json as simplejson
import time

DISQUS_SECRET_KEY = 'SECRET KEY FROM API'
DISQUS_PUBLIC_KEY = 'PUBLIC KEY FROM API'


def get_disqus_sso(user_id=None, username=None, email=None):
    if user_id:
        user_data = {
            'id': user_id,
            'username': username,
            'email': email,
        }
    else:
        user_data = {}
    # create a JSON packet of our data attributes
    data = simplejson.dumps(user_data)
    # encode the data to base64
    message = base64.b64encode(data)
    # generate a timestamp for signing the message
    timestamp = int(time.time())
    # generate our hmac signature
    sig = hmac.HMAC(DISQUS_SECRET_KEY,
                    '%s %s' % (message, timestamp), hashlib.sha1).hexdigest()

# return a script tag to insert the sso message
    return """<script type="text/javascript">
    var disqus_config = function() {
        this.page.remote_auth_s3 = "%(message)s %(sig)s %(timestamp)s";
        this.page.api_key = "%(pub_key)s";
        this.sso = {
        name:   "Screener Talks",
        button:  "http://www.screener.in/static/img/social/disqus.png",
        url:     "http://www.screener.in/register/",
        logout:  "http://www.screener.in/logout/",
        };
    }
    </script>""" % dict(
        message=message,
        timestamp=timestamp,
        sig=sig,
        pub_key=DISQUS_PUBLIC_KEY,
    )

In views.py:

def _get_disqus_sso(user):
    if user.is_authenticated():
        disqus_sso = get_disqus_sso(
            user.id,
            user.display_name,
            user.email, )
    else:
        disqus_sso = get_disqus_sso()
    return disqus_sso

def some_view(request):
    ...
    disqus_sso = _get_disqus_sso(request.user)
    return render(request, "template.html", {"disqus_sso": disqus_sso})

And in template.html:

    <div id="disqus_thread"></div>
    <script type="text/javascript">
        var disqus_shortname = 'SITESHORTNAME'; 
        var disqus_identifier = 'POST ID';
        var disqus_title = 'POST TITLE';
        /* * * DON'T EDIT BELOW THIS LINE * * */
        (function() {
            var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
            dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
            (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
        })();
    </script>
    <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
    <a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
    {{ disqus_sso|safe }}

Much of the code is from various snippets on GitHub, but unfortunately I couldn't locate the exact sources. This might be helpful though: https://github.com/jumoconnect/openjumo/blob/master/jumodjango/lib/disqus.py

like image 156
Pratyush Avatar answered Sep 22 '22 02:09

Pratyush


There isn't enough information to figure out what the issue is, as everything available checks out so far. Here's what we need to figure out the issue:

  1. Do you see all the login buttons besides the SSO login option?
  2. How are you generating the hmac string? Are you using the corresponding secret key to your public key, and the same timestamp that you're signing the end of the remote_auth_s3 string with?
  3. Are you testing on a domain that you entered as a trusted domain in your API application settings?
  4. Are you seeing the payload get sent in the threadDetails.json request? Here's how to check: http://help.disqus.com/customer/portal/articles/1148640

I'll update the answer based on those.

I do have a few suggestions to fix some other issues I saw.

First, It looks like you're just missing some of the required configuration variables for SSO. These are all the possible ones:

this.sso = {
          name:   "SampleNews",
          button:  "http://example.com/images/samplenews.gif",
          icon:     "http://example.com/favicon.png",
          url:        "http://example.com/login/",
          logout:  "http://example.com/logout/",
          width:   "800",
          height:  "400"
    };

Out of these, name, url, and logout should be used at minimum - so make sure you include those.

Second, don't use relative URLs in the this.sso configuration. Because these URLs are used within the iframe (technically disqus.com), some browsers will resolve the URLs as http://disqus.com/profile/login/, which will obviously not go where intended.

like image 42
Ryan V Avatar answered Sep 22 '22 02:09

Ryan V