3

更新 3 : REST API 権限: ビューセットを定義するときに、適切な権限クラスを関連付けます...

class TopSecretViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = myModels.TopSecret.objects.all()
    serializer_class = mySerializers.TopSecretSerializer
    permission_classes = (myAuth.MyIsAuthenticated,)

更新 2 : REST 認証

編集:ユーザーと一緒に Permissions オブジェクトを返します

設定.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
       'app.authentication.MyAuthentication',
    )

authentication.py

class MyIsAuthenticated(BasePermission):
    """
    Allows access only to authenticated, if it is AnnoymousUser we 
    don't allow access.  There will be more code here - but this is 
    good for the example
    """

    def has_permission(self, request, view):
        if request.user and isinstance(request.user, myModels.User):
            return True
        return False


######################################################
# TODO: return the apropiate permissions
######################################################    
class MyAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request):
        cookies = request.COOKIES
        if 'user' in cookies:
            userCookie = request.COOKIES['user']
            userJson = base64.b64decode(userCookie)
            userDict = json.loads(userJson)
            userId = userDict['user_id']

            if not userId:
                return None

            try:
                user =myModels.User.objects.get(user_id=userId)
            except myModels.User.DoesNotExist:
                raise exceptions.AuthenticationFailed('No such user')

            return (user, MyIsAuthenticated)
        return None

更新:ソリューションの作業

django restframework ビューセット:

編集ユーザーオブジェクトのbase64エンコードCookieを追加しました(JSONペイロードでも返されます)

#####################################################################
# handles two REST APIs GET/list users (through the mixin and) in 
#     accordance to the rules of the UserLoginSerializer
#     the POST/create - and while I don't like handling this in the
#     create method, this is the post of the login credentials
#####################################################################
class UserViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = myModels.User.objects.all()
    serializer_class = mySerializers.UserLoginSerializer

    def set_cookie(response, key, value, days_expire=7, host=''):
        if days_expire is None:
            max_age = 1 * 24 * 60 * 60  #1 day
        else:
            max_age = days_expire * 24 * 60 * 60
        expires = datetime.strftime(datetime.utcnow() + timedelta(seconds=max_age),"%a, %d-%b-%Y %H:%M:%S GMT")

        host = host.split(':')[0]

        response.set_cookie(key, value, max_age=max_age, expires=expires, domain=host)
        return response

    def create(self, request):
        login_email = request.DATA['email']
        login_password = request.DATA['password']
        login_password = login_password
        user = myModels.User.objects.get(email=login_email)

        md5 = hashlib.md5()
        md5.update(login_password)
        login_password_md5 = unicode(md5.hexdigest())

        if (user and login_password_md5 == user.password):

            user.last_login = datetime.now()
            user.save()

            role = 4 #verfied user
            responseData = {
                    'user_id': user.user_id
                    , 'firstName': user.firstname
                    , 'lastName': user.lastname
                    , 'email': login_email
                    , 'role': role
            }

            return  set_cookie(
                Response(responseData)
                , 'user'
                , base64.b64encode(json.dumps(responseData, ensure_ascii=False))
                , days_expire=1
                , host = request.META['HTTP_HOST'])

        else:
            role  = 1 #anonymous
            return Response({'email': login_email, 'role': role, 'message': 'Unknown Email or Incorrect Password'
                , 'user_id':  -1, 'first_name': '' , 'last_name': ''})

元の投稿

編集来年かそこらでPythonに完全に移植できるようになるまで、これをPHPレガシーアプリケーションに接続して並行して実行しています。したがって、組み込みの Django Authentication の魅力はそれほど魅力的ではありません

たくさんのティーザーコンテンツを表示する単一ページの Web アプリがあります。コンテンツをクリックすると、ログインを求められます。画面にオーバーレイされた div を使用してログイン フォームを表示し、このフォームのデータを認証のためにサーバーに送信したいと考えています。

私たちのサイトは現在 HTTPS で実行されているため、現時点ではシンプルなソリューションが最適だと考えています。

質問 1: ログイン サービス: POST REST 要求でログインを実行することを考えていましたが、これが正しいアプローチであるかどうかはわかりません。

質問 2: Django-Rest-Framework を使用して、認証とログイン サービスを調整する必要があります。Cookie を読み取り、適切なユーザーと権限を識別するカスタム認証を作成することを考えていました。これは合理的な解決策のように思えますか?

質問 3: クッキー? クッキーはどこに書くべきですか?ログインサービスの一部としてサーバーからの応答に埋め込む必要がありますか、またはログインが成功したときにjs /クライアント側に書き込む必要があります。おそらく前者の方が良い方法であり、許可することができます将来、すべてのコードを 1 つの場所 (サーバー) に格納して、Cookie を暗号化 [復号化] します。ログインが成功したときにJavaScript側にCookieを書き込む方が良いと思う人はいますか?

私のクライアント スタック: AngularJs、RESTangular (Cookie を適切に取得します)、およびその他のそれほど興味深いものではありません

私のサーバー スタック: Python 2.7、Django 1.5、Django-Rest-Framework

いつも - よろしくお願いします!

4

2 に答える 2

0

解決策を明らかにしながら、元の投稿で段階的に回答しました。基本的に手順は

  1. 認証を実行するための REST サービスを作成します。django rest フレームワークを使用する際に、GenericViewet から継承し、create メソッドをオーバーライドして POST を処理しました。認証されたユーザーを表す応答ペイロードとして UI に JSON を返し、同じオブジェクトを使用して Cookie もダンプしました。リターン応答を待っているコントローラーのために、リターン ペイロードを angularjs フロント エンドにプラグインする方がよいと考えられます。Cookie は、再訪問者のためにアプリケーションが起動したときに読み取ることができ、さらに REST 要求で渡されます。

  2. 独自の認証クラスを作成し、REST フレームワーク (設定) にプラグインします。私の場合、Cookie を読み取り、DB でユーザーを見つけます。特定の REST Api にアクセス許可を関連付けたい場合は、独自のアクセス許可クラス (小さくてシンプル) を作成する必要があります。上記の例では、インスタンス化されたユーザー クラスが User クラスのインスタンスであることを確認するだけですが、最終的には個々の権限を確認します。

  3. 適切なビューセットに権限を追加します

于 2013-10-10T15:17:04.260 に答える
0

REST API は、残りを使用してすべてを行う必要があるという意味ではありません。

使用および操作しているデータには REST インターフェイスを使用し、認証にはカスタム ハンドラーを使用することをお勧めします。

このようにして、組み込みの django 認証を使用しながら、残りの API をデータに使用できます。必要のないものを再発明する必要はありません。

于 2013-10-08T15:41:03.623 に答える