Hello,

I am trying multiple login methods- Twitter or Facebook.
I want to know the best practice to support multiple login methods 
(multiple OAuth).

Currently, I got a problem.
I can redirect to login form of facebook or twitter. 
But after I successfully logged in the OAuth providers, I can't log in my 
service.

Here is my code.

In db.py, I defined two classes TwitterAccount and FacebookAccount

from gluon.contrib.login_methods.oauth20_account import OAuthAccount

class FaceBookAccount(OAuthAccount):
    """OAuth impl for Facebook"""
    AUTH_URL="https://graph.facebook.com/oauth/authorize";
    TOKEN_URL="https://graph.facebook.com/oauth/access_token";
    user = None
    graph = None
    def __init__(self, g=globals()):
        OAuthAccount.__init__(self, g,
                              FACEBOOK_CLIENT_ID,
                              FACEBOOK_CLIENT_SECRET,
                              self.AUTH_URL,
                              self.TOKEN_URL)
        self.graph = None

    def get_user(self):
        if not self.accessToken():
            return None
            
        if not self.graph:
            self.graph = GraphAPI((self.accessToken()))
            
        if not self.user:
            try:
                self.user = self.graph.get_object("me")
            except GraphAPIError:
                return None
                
        return self.user
        



import oauth2 as oauth
from gluon.contrib.login_methods.oauth10a_account import OAuthAccount as 
OAuthAccount10a

class TwitterAccount(OAuthAccount10a):
    AUTH_URL = "http://twitter.com/oauth/authorize";
    TOKEN_URL = "https://twitter.com/oauth/request_token";
    ACCESS_TOKEN_URL = "http://twitter.com/oauth/access_token";
    def __init__(self, g=globals()):
        OAuthAccount10a.__init__(self, g,
                              consumer_key,
                              consumer_secret,
                              self.AUTH_URL,
                              self.TOKEN_URL,
                              self.ACCESS_TOKEN_URL)
                              
    def get_user(self):        
        if self.accessToken() is not None:            
            client = oauth.Client(self.consumer, self.accessToken())
            resp, content = 
client.request('http://api.twitter.com/1/account/verify_credentials.json')
            if resp['status'] != '200':
                # cannot get user info. should check status
                return None
            u = json.loads(content)            
            return dict(username=u['screen_name'], name=u['name'], 
registration_id=str(u['id']))



and then, make two instances

# TWITTER
twitter_login = TwitterAccount(globals())

# FACEBOOK
facebook_login = FaceBookAccount(globals())

# set
crud.settings.auth = None                      # =auth to enforce 
authorization on crud
auth.settings.actions_disabled=['register','change_password','request_reset_password','profile']
auth.define_tables()



In controller, 
def user():
    
    if len(request.args) > 1:    
        if request.args[0] == 'login' and request.args[1] == 'facebook':
            auth.settings.login_form=facebook_login
        elif request.args[0] == 'login' and request.args[1] == 'twitter':
            auth.settings.login_form=twitter_login

    return dict(form=auth())



But it seems that I need to set 'auth_settings.login_form' in db.py before 
calling auth.define_tables()


If I set

auth.settings.login_form=twitter_login
auth.define_tables()

or 

auth.settings.login_form=facebook_login
auth.define_tables()

in db.py, each works well.


Is there any way to set auth.settings.login_form dynamically in controller?

I think it may impossible, because auth creates tables before knowing 
proper fileds (like username).

Then, how can I set multiple login form?

Or right way to support multiple login? (except janrain)


Thank you very much.

-- 



Reply via email to