スポンサーサイト

0

    一定期間更新がないため広告を表示しています


    • 2014.12.23 Tuesday
    • -
    • -
    • -
    • -
    • -
    • by スポンサードリンク

    djangoでクッキー利用しない認証は可能か?(ドツボ中)

    0
      ここ2か月ばかり怒涛のように仕事と親戚付き合いに忙殺されてブログ書けませんでした。

      ようやく一段落ついた、と思ったらまたハマったので「ヘルプ!」を兼ねてメモしときます。
      djangoで作ったPC版コミュニティサイトに携帯サイトをつけようと思ったんですが、djangoのcontrib.authってクッキー必須なんですよね(http://michilu.com/django/doc-ja/authentication/)

      で、クッキーの使える携帯(AU現行全機種&WILLCOM&SoftBankの一部機種)は問題なくエンコードとテンプレを変更するだけで使えるんですが、問題はi-mode様。
      奴はクッキーが使えないので、login_requiredしてるビューがことごとくログインフォームにぶっ飛ばされて、その後ログインができない状態になります(当然)。

      自分の携帯はAUなので、自分で使うだけならいいんですが、i-modeで使いたい人がいるので、「GETでセッションIDを持ってる人」かつ「リモートアドレスがi-mode」の人を対象に、特別なログイン方式を使いたいと思ってるんです。

      最初に考えたのが、
      ★ドコモ携帯用のビューを全部新たに書いて、login_requiredを外し、1回1回GETをチェック。→→書くビューの数が膨大になり、非常にめんどくさい。が、確実に実装できそう。

      面倒なのはいやなので次に考えたのが
      ★login_requiredデコレータをカスタマイズ。user.is_authenticated()をチェック→認証不可ならGETのセッションIDをチェック→両方外したらログインに飛ばす というmyprj.myapp.mydeco.login_requiredを書き、現行ビューのインポート先をcontrib.auth.decoratorsから変更する。
      →→デコレータの書き方さえできれば、楽に実装できそう。

      で。
      早速やってみたんですが、結論としてうまくデコレータが書けず、エラーでドツボにはまってます。(´・ω・`)
      とりあえずdjango.contrib.auth.decorators.user_passes_testを参考に、

      from django.contrib.auth import REDIRECT_FIELD_NAME
      from django.contrib.auth.models import User
      from django.contrib.sessions.models import Session
      from django.http import HttpResponseRedirect
      from urllib import quote

      def login_required():
      login_url = "/accounts/login/"
      def _dec(view_func):
      def _checklogin(request, *args, **kwargs):
      if request.user.is_authenticated():
      return view_func(request, *args, **kwargs)
      else:
      try:
      request.META['HTTP_USER_AGENT'].index("DoCoMo")
      data = Session.objects.get(pk=request.GET['sessionid']).get_decoded()
      user = User.objects.get(id=data['user_id'])
      return view_func(request, *args, **kwargs)
      except:
      pass
      return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, quote(request.get_full_path())))
      _checklogin.__doc__ = view_func.__doc__
      _checklogin.__dict__ = view_func.__dict__

      return _checklogin
      return _dec

      というデコレータを書いたら、djangoのエラー画面で「login_requiredは引数を持たないって書いてるけど引数1個もらっちゃってるよ!」と怒られました。

      じゃあ。ということで
      def login_required()を
      def login_required(request)とか
      def login_required(view_func)とか
      色々変えてみたんですが、今度はdjangoのエラー画面まで行かず500エラー。
      エラーログを見るとresponseオブジェクトがどうのこうので怒られてる様子。

      GETで持たせるのをセッションIDを持たせる形じゃなくて、携帯の無料HPスペース系にありがちなユーザ名&簡単にハッシュしたパスワードにする形も考えたんだけど、このデコレータでつまづいてる限りそれも無理だよねー。
      認証バックエンドとかミドルウェアの類から自分で書かないとダメ??
      ああ困ったな。誰かヘルプw


      …携帯版だけPHP手書きで書き直そうかどうしようか、一瞬本気で悩んだ。
      一度djangoのテンプレート継承の楽さに慣れてしまったらsymfonyとかPHP手書きには戻れないorz

      そして、djangoはフレームワークというものの教育用には良いけれど(例:強制的にMVC(MTV)を分離させてくれる等)、CMS系用途に限定して使ったほうがいいのかなと思ったw
      トリッキーなハックをしなくて済むように、もう少し自由度がほしいというか。


      スポンサーサイト

      0

        • 2014.12.23 Tuesday
        • -
        • 16:23
        • -
        • -
        • -
        • -
        • by スポンサードリンク

        コメント
        お久しぶりです :)

        Djangoで携帯サイトの構築について先日の勉強会で話した人がいらっしゃいます。
        映像があるので、
        http://stage6.divx.com/user/kzn/blog/25751/
        のsakatokuと入っているURLをダウンロードもしくは見ると分かるかもしれませんよ:)

        直接解決できるようなコメントではなくてすみませんorz
        参考にされているuser_passes_testは、チェック用の関数を外側から渡せるようになっています。
        今回のように内側にチェックロジックを閉じ込めている場合には、関数のネストを一段階少なくすれば正しいデコレータになります。
        デコレータは、ちょっと難しいですよね :(
        DoCoMo携帯を持っていないので動作確認はしていませんが、きっとこんな感じのデコレータになると思います。
        http://dpaste.com/hold/18985/

        • everes
        • 2007/09/09 12:29 AM
        >常山さん
        動画全部拝見しましたm(_ _)m
        非常に参考になることがいっぱいでした。
        感謝です!ありがとうございました。

        >everesさん
        わざわざコード見ていただいて、ありがとうございます!
        django以前のpythonデコレータの書き方の問題でしたね(汗
        とりあえずエラーは出なくなりましたので、実機のdocomo携帯を握ってテストをしたいと思います。
        本当に助かりましたm(_ _)m
        • もも
        • 2007/09/10 9:43 AM
        コメントする








           
        この記事のトラックバックURL
        トラックバック

        PR

        calendar

        S M T W T F S
           1234
        567891011
        12131415161718
        19202122232425
        2627282930  
        << November 2017 >>

        twitter

        selected entries

        categories

        archives

        recent comment

        • 結局CodeIgniter用汎用Modelクラス&汎用CRUDスクリプトを書きました
          プログラマー
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          ななうぇぶ
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • WindowsのPCで開発するphperがxhprofを使う方法
          ななうぇぶ
        • WindowsのPCで開発するphperがxhprofを使う方法
          川本
        • [バッドノウハウ]Symfony2で別テーブルの集計項目を一覧に含めたいとき
          よし
        • Symfony Advent Calendar JP 2012 day 14 - vendorをcomposerで管理しているプロジェクトにcomposerを使わずにバンドルを追加したときのautoloadの書き方
          77web
        • Symfony Advent Calendar JP 2012 day 14 - vendorをcomposerで管理しているプロジェクトにcomposerを使わずにバンドルを追加したときのautoloadの書き方
          ktz

        recent trackback

        • HTMLの表(TABLE)のセル(TD)に斜線を引くjavascriptライブラリ slash.js 作っちゃいました
          常山日記
        • django対symfony 日本語メール送信(その1 symfony編)
          CPA-LABテクニカル
        • CodeIgniterでユーザー認証
          されどLAMPな日々
        • 久々にdjangoを最新版にしたらHTMLがエスケープされちゃった!!(解決済み)
          常山日記
        • FastCGIを諦めてmod_pythonを使う。Apacheのアップグレード
          サーバー用語集
        • さくらインターネット、sqlite3でdjango@CGI版を使う際の設定メモ
          常山日記
        • さくらインターネット スタンダードプランでdjango使ってる方、DBは?
          mitszoの日記
        • python多次元リストをsort(並べ替え)する方法?
          mitszoの日記
        • フォームから送信した値とrequest.POSTの挙動($_POST@PHPとの比較)
          Humming Via Kitchen
        • 日本語テキストをtruncate@django(Python全般にも??)
          常山日記

        recommend

        links

        profile

        search this site.

        others

        mobile

        qrcode

        powered

        無料ブログ作成サービス JUGEM