19

In django-social-auth, there are a few instances where a backend will raise a ValueError (such as when a user cancels a login request or if a user tries to associate with an account that's already been associated with another User). If a User runs into one of these scenarios, they'll be presented with a 500 error on your site.

So, what's the best way to catch these? I'd prefer to be able to display a useful message (via the messages framework) when this happens, but I'm at a loss as to the best way to do this.

I'm thinking about writing my own view (in a separate app) that just wraps social_auth's associate_complete view, but this seems clunky... any ideas?

I could fork django-social-auth and customize this behavior, but I'd prefer not to maintain a separate fork--especially since I can't assume everone would want to handle these Exceptions in the same manner.

4

4 に答える 4

19

かなり古い質問ですが、最近のバージョンの DSA はカスタム例外プロセッサをサポートしており、例外メッセージでやりたいことが何でもできることに言及する価値があります。デフォルトのバージョンではメッセージ アプリに保存されます。

また、役に立たない使用の代わりに例外が区別されるようになりましたValueError。ドキュメントhttp://django-social-auth.readthedocs.org/en/latest/configuration.htmlを確認してください。

更新 (2013 年 8 月 13 日):

上記の変更を投稿したので、DSA には例外ミドルウェアがあり、有効にすると例外メッセージが jango 組み込みメッセージ アプリに保存されます。ミドルウェアをサブクラス化し、それにカスタム動作を追加することをお勧めします。http://django-social-auth.readthedocs.org/en/latest/configuration.html#exceptions-middlewareでドキュメントを確認してください

サンプル ミドルウェア:

# -*- coding: utf-8 -*-
from social_auth.middleware import SocialAuthExceptionMiddleware
from social_auth.exceptions import AuthFailed
from django.contrib import messages

class CustomSocialAuthExceptionMiddleware( SocialAuthExceptionMiddleware):

    def get_message(self, request, exception):
        msg = None
        if (isinstance(exception, AuthFailed) and 
            exception.message == u"User not allowed"):
            msg =   u"Not in whitelist" 
        else:
            msg =   u"Some other problem"    
        messages.add_message(request, messages.ERROR, msg)     
于 2012-03-03T01:41:27.900 に答える
13

私は同じ問題に遭遇しましたが、少なくとも現時点では、ラッパービューを作成することがこの状況を処理する最良の方法であるようです。これが私が行った方法です:

def social_auth_login(request, backend):
    """
        This view is a wrapper to social_auths auth
        It is required, because social_auth just throws ValueError and gets user to 500 error
        after every unexpected action. This view handles exceptions in human friendly way.
        See https://convore.com/django-social-auth/best-way-to-handle-exceptions/
    """
    from social_auth.views import auth

    try:
        # if everything is ok, then original view gets returned, no problem
        return auth(request, backend)
    except ValueError, error:
        # in case of errors, let's show a special page that will explain what happened
        return render_to_response('users/login_error.html',
                                  locals(),
                                  context_instance=RequestContext(request))

そのためにセットアップする必要がありますurl

urlpatterns = patterns('',
    # ...
    url(r'^social_auth_login/([a-z]+)$',  social_auth_login, name='users-social-auth-login'), 
)

そして、テンプレートで以前と同じように使用します。

<a href="{% url 'users-social-auth-login' "google" %}">Log in with Google</a>

質問がされてから2か月後でも、これが役立つことを願っています:)

于 2011-08-24T08:26:50.010 に答える
6

ソーシャル認証ミドルウェアを追加する必要があります:

MIDDLEWARE_CLASSES += ('social_auth.middleware.SocialAuthExceptionMiddleware',)

エラーが発生した場合、ユーザーはエラー URL (設定の LOGIN_ERROR_URL) にリダイレクトされます。

詳細な説明については、ドキュメントを参照してください: http://django-social-auth.readthedocs.org/en/latest/configuration.html#exceptions-middleware

于 2013-08-28T07:50:27.530 に答える
5

私のアプリのviews.pyで:

from social_auth.views import associate_complete

def associate_complete_wrapper(request, backend):
    try:
        return associate_complete(request, backend)
    except ValueError, e:
        if e and len(e.args) > 0:
            messages.error(request, "Failed to Associate: %s" % e.args[0])
    return redirect(reverse('pieprofile-edit-account'))

次に、ルート URLconf で (これらの URL パターンの順序に注意してください):

url(r'^associate/complete/(?P<backend>[^/]+)/$', 'myapp.views.associate_complete_wrapper'),
url(r'', include('social_auth.urls')),

associate_complete_wrapperの URL は基本的に social_auth のsocialauth_associate_completeURL を乗っ取っています。

于 2011-08-26T02:50:58.287 に答える