8

私は基本的に、特定のユーザーのFacebook IDを保存して、Facebook経由でより多くの資料を受け取ることができます。理想的には、javascriptもクッキーも使用していない、サーバー側だけのソリューションがほしいですが、例はなく、方向性があるので、私たちが議論できるものをまとめました。ここで私はちょうど私のウェブサイトのためのOAuthのダイアログにユーザーをリンクするとき、私は作品を考えるコードは次のとおりです。Facebook OAuth 2.0を完全にサーバサイドにするにはどうすればいいですか?

https://www.facebook.com/dialog/oauth?client_id=164355773607006&redirect_uri=http://www.kewlbusiness.com/oauth

その後、私はユーザデータを取得するには、このようにそれを扱う:

class OAuthHandler(webapp2.RequestHandler): 
    def get(self): 
     args = dict(
     code = self.request.get('code'), 
     client_id = facebookconf.FACEBOOK_APP_ID, 
     client_secret = facebookconf.FACEBOOK_APP_SECRET, 
     redirect_uri = 'http://www.koolbusiness.com/oauth', 
    ) 
     file = urllib.urlopen("https://graph.facebook.com/oauth/access_token?" + urllib.urlencode(args)) 
     try: 
     token_response = file.read() 
     finally: 
     file.close() 
     access_token = cgi.parse_qs(token_response)["access_token"][-1] 
     graph = facebook.GraphAPI(access_token) 
     user = graph.get_object("me") 
     self.response.out.write(user["id"]) 
     self.response.out.write(user["name"]) 

とそうこれは私が望んでいない不愉快なjavascriptやクッキーがたくさんなくても私のウェブサイトのために "Facebookでログイン"することができます。私は自分のウェブサイトで「Facebookでログイン」を有効にしたかったのです。クッキーなしで、JavaScriptなしで動作するはずですが、あなたがするようにしようとする最初のものはJavascriptとCookieです。だから、私はクッキーなしでjavascriptなしで動作するようなソリューションを作っただけです.OAuth 2.0:私の "ソリューション"について何か言いたいことはありますか?私が探している実用的な使い方は、FBユーザーが自分のウェブサイト上で何をしたのか、そして標準化されつつある方法でログインするためにFacebookのアカウントを許可するという単純な機能を可能にすることです。

私はちょうどjavascript SDKなしで、クッキーなしで動作しなければならないと思っていました。この「解決策」の長所と短所を教えてください。私はJavascript + Cookieよりもはるかに優れていると思います。なぜなら、最小限の例が100%サーバサイドであるように見える場合、JavaScriptとCookieを使用するのはどうしてですか?

はそれだけのpython、右のようで、右に動作し、私もdatatoreでユーザデータを使用し、JavaScriptとクッキーなしなしでフロントページに私のFB名をレンダリングすることができます 更新あなた

をありがとう

Facebookユーザーの変数fbuserとgoogleユーザーの可変ユーザーは、今や私のウェブサイトにバグなく不必要なjavascript + cookieなしでFacebookを使用することを認めています。

私は自分のウェブサイトから自分のFacebookの名前を表示して見ることができました。これは最終的にjavascriptに依存せず、クッキーを必要としないという仕方で機能します。

サーバサイドのOAuth 2.0が最もクリーンなソリューションである場合、ドキュメンテーションでjavascript + cookieが推奨されるのはなぜですか?あなたがjavascriptまたはcookieを使用するかどうかに依存しないので、これが最良の解決策であることに同意しますか?

更新 可能性のある重複した質問私は今、他のみんなは、サーバーコードでログアウトできなかったことを見てきたとき、彼らはJavascript SDKに頼らなければならなかったと要件は、それはしていないJavaScriptで動作するはずですしなければならないことをすることができ私はデバッグをしてクッキーを "クリア"し、クッキーの名前を変更しなければならなかったことが分かりましたが、私のプロジェクトがこれを解決したとあなたのコメントやテストをしたいと思います。このようなログアウトリンクはうまくいくはずですが、そうではありません。私がログアウトした場合は二回、それが動作し、これは私がそれを修正することができますが、私はまだログアウトは第二のヒット必要となりますかわからないので、奇妙なバグである理由です:

https://www.facebook.com/logout.php?next=http://www.myappengineproject.com&access_token=AAACVewZBArF4BACUDwnDap5OrQQ5dx0jsHEKPJkIJJ8GdXlYdni5K50xKw6s8BSIDZCpKBtVWF9maHMoJeF9ZCRRYM1zgZD

を私はしなかったように見えますOAuth 2.0サーバサイドのソリューションのためにjavascriptを完全に避けようとする唯一のものです。人々はすべてを行うことができますが、彼らはログアウトできませんでした:

Facebook Oauth Logout

のFacebookでのOAuth 2.0の公式ドキュメントは言う:あなたがそれらを向けることによって、自分のFacebookのセッションのうち、ユーザがログインすることができ

次URL:

https://www.facebook.com/logout.php?next=YOUR_URL&access_token=ACCESS_TOKEN

YOUR_URLがあなたのサイトのDOMAでURLでなければなりませんアプリ内で定義されているようになりました( デベロッパーアプリ)。

私は、サーバー側のすべてをやってみたかったと私はログアウト・リンクが機能しないように、リンクへの提案方法は、クッキーを離れることがわかった: https://www.facebook.com/logout.php?next=http://{{host}}&access_token={{current_user.access_token}} それはリダイレクトんが、それは、ユーザーたちののは記録されません。私のウェブサイト。これは私に変わっていたので、Heisenbugのように思えました。私はとにかく実際にユーザーがログアウトされるように、クッキーを操作するハンドラと機能性を達成することができるように見えた:

class LogoutHandler(webapp2.RequestHandler): 
    def get(self): 
     self.set_cookie("fbsr_" + facebookconf.FACEBOOK_APP_ID, None, expires=time.time() - 86400) 
     self.redirect("/") 
    def set_cookie(self, name, value, expires=None): 

     if value is None: 
      value = 'deleted' 
      expires = datetime.timedelta(minutes=-50000) 
     jar = Cookie.SimpleCookie() 
     jar[name] = value 
     jar[name]['path'] = '/' 
     if expires: 
      if isinstance(expires, datetime.timedelta): 
       expires = datetime.datetime.now() + expires 
      if isinstance(expires, datetime.datetime): 
       expires = expires.strftime('%a, %d %b %Y %H:%M:%S') 
      jar[name]['expires'] = expires 
     self.response.headers.add_header(*jar.output().split(': ', 1)) 

だから、/認証/ログアウトにハンドラをマッピングし、効果的にリンクにこれを設定します

def get(self): 
    fbuser=None 
    profile = None 
    access_token = None 
    accessed_token = None 
    logout = False 
    if self.request.get('code'): 
     args = dict(
     code = self.request.get('code'), 
     client_id = facebookconf.FACEBOOK_APP_ID, 
     client_secret = facebookconf.FACEBOOK_APP_SECRET, 
     redirect_uri = 'http://self.get_host()/', 
    ) 
     file = urllib.urlopen("https://graph.facebook.com/oauth/access_token?" + urllib.urlencode(args)) 
     try: 
     token_response = file.read() 
     finally: 
     file.close() 
     access_token = cgi.parse_qs(token_response)["access_token"][-1] 
     graph = main.GraphAPI(access_token) 
     user = graph.get_object("me") #write the access_token to the datastore 
     fbuser = main.FBUser.get_by_key_name(user["id"]) 
     logging.debug("fbuser "+fbuser.name) 

     if not fbuser: 
     fbuser = main.FBUser(key_name=str(user["id"]), 
          id=str(user["id"]), 
          name=user["name"], 
          profile_url=user["link"], 
          access_token=access_token) 
     fbuser.put() 
     elif fbuser.access_token != access_token: 
     fbuser.access_token = access_token 
     fbuser.put() 

    current_user = main.get_user_from_cookie(self.request.cookies, facebookconf.FACEBOOK_APP_ID, facebookconf.FACEBOOK_APP_SECRET) 
    if current_user: 
     graph = main.GraphAPI(current_user["access_token"]) 
     profile = graph.get_object("me") 
     accessed_token = current_user["access_token"] 

:私のコードのいくつかの他の部分はのOAuth通信用のOAuthトークンとクッキーのルックアップを処理している

(うまくいけば、Facebookの外のユーザーにログインし、未検証せずに)私のサイトのユーザをログアウト私はloginhaを作っていないndler loginは基本的に私のルートリクエストハンドラの上のコードです。次のように私のユーザークラスは次のとおりです。

class FBUser(db.Model): 
    id = db.StringProperty(required=True) 
    created = db.DateTimeProperty(auto_now_add=True) 
    updated = db.DateTimeProperty(auto_now=True) 
    name = db.StringProperty(required=True) 
    profile_url = db.StringProperty() 
    access_token = db.StringProperty(required=True) 
    name = db.StringProperty(required=True) 
    picture = db.StringProperty() 
    email = db.StringProperty() 

私は2つの基本的なプロバイダ enter image description here を一緒に嘲笑そして、私はFacebookのユーザーとGoogleのユーザーとあるユーザーのための変数fbuserのための変数のユーザーのための変数CURRENT_USERを使用しますログインしているため、Cookieに一致しません。

私が使用してクッキーの検索コードは次のようであると私はそれを理解し、それは私が何をしたいんだと思います:

def get_user_from_cookie(cookies, app_id, app_secret): 
    """Parses the cookie set by the official Facebook JavaScript SDK. 

    cookies should be a dictionary-like object mapping cookie names to 
    cookie values. 

    If the user is logged in via Facebook, we return a dictionary with the 
    keys "uid" and "access_token". The former is the user's Facebook ID, 
    and the latter can be used to make authenticated requests to the Graph API. 
    If the user is not logged in, we return None. 

    Download the official Facebook JavaScript SDK at 
    http://github.com/facebook/connect-js/. Read more about Facebook 
    authentication at http://developers.facebook.com/docs/authentication/. 
    """ 
    logging.debug('getting user by cookie') 
    cookie = cookies.get("fbsr_" + app_id, "") 
    if not cookie: 
     logging.debug('no cookie found') 
     return None 
    logging.debug('cookie found') 
    response = parse_signed_request(cookie, app_secret) 
    if not response: 
     logging.debug('returning none') 
     return None 

    args = dict(
     code = response['code'], 
     client_id = app_id, 
     client_secret = app_secret, 
     redirect_uri = '', 
    ) 

    file = urllib.urlopen("https://graph.facebook.com/oauth/access_token?" + urllib.urlencode(args)) 
    try: 
     token_response = file.read() 
    finally: 
     file.close() 

    access_token = cgi.parse_qs(token_response)["access_token"][-1] 
    logging.debug('returning cookie') 
    return dict(
     uid = response["user_id"], 
     access_token = access_token, 
    ) 

私はこの問題を解決するためにクッキーを学ばなければならなかったと私はあなたがより多くのコメントができると思います。あなたが認証しようとしているとき

のJavaScript /クッキー使用されています。ウェルカムメッセージを出力する3つの変数、Googleユーザーに1つ、Facebookのユーザーとの回答で述べた場合の変数fbuserログインのための1が必要新しい ユーザー。あなたのデータベースには存在しません。あなたは彼の accessTokenを持っていません。

私は3つの変数を使用しなければなりませんでした。

{% if user or current_user or fbuser %} 
     <div id="user-ident"> 
      <span>{% trans %}Welcome,{% endtrans %} <b>{{ current_user.name }}{% if not current_user and user %}{{ user.nickname() }}{% endif %}{% if not current_user and not user and fbuser %}{{ fbuser.name }}{% endif %}</span> 
     </div> 
     {% endif %} 

答えて

1

JavaScript/Cookiesは、新しいユーザーを認証しようとしているときに使用されます。あなたのデータベースには存在せず、彼のaccessTokenはありません。

ユーザーのアクセストークンを持っている場合は、必要に応じてcookie/javascriptを使用せずにHTTP経由で任意のプログラミング言語からFacebook APIにアクセスできます。 Pythonクライアントがあります。たとえば、http://github.com/pythonforfacebook/facebook-sdkhttps://github.com/facebook/python-sdk

+0

リンクありがとうございます。この例は私がプレーンなOAuthを探しているものであり、セッション管理にクッキーが使用されていることを理解しています。私はすべてが私のログアウトを除いて動作すると思います。例は、他の人がjavascriptなしでこれをやろうとしているのを見て、それが複雑であることを見て以来、logouthandlerを非常に便利にしてくれたと思っています –

+0

logouthandlerは私のために働きます。 (ログアウト)。 Facebookが提供するリンクはクッキーをクリアしないので、ユーザーはログインしたままになります –

+1

ゲームの最後になります。しかし、このリンクは壊れているようです。更新されたものは次のとおりです:https://github.com/pythonforfacebook/facebook-sdk/ – damzam

1

が見つかりました。良い見え、それは単なるfb以上のものを満たす。 https://code.google.com/p/gae-simpleauth/

+1

これは私が今日使用しているもので、正方形でも動作します。私は自分自身をOauthのプロバイダにしようと考えています。私は別のプロバイダを追加するのと同じ方法で自分のサイトを追加できます。多くの異なるユーザーモデルを作成することは不利でしたが、今でも 'ndb.Expando'というwebapp2のユーザーモデルを使用することができます。私は新しいアプリケーションを再配布しなくてもプロバイダを追加できるようにsimpleauthを開発できると思います。管理者のWebセクションからプロバイダを追加できるように、データストア内にプロバイダデータも保持しています。興味深いもの: –

+0

それがどうなるか教えてください。 –

関連する問題