4

私は Grails で小さな webapp を作成しており、すべてのユーザーが認証されていることを確認するために、次のフィルターを使用しています。

class LoginFilters {
  static filters = {
    loginCheck(controller:'*', action:'*') {
      before = {
        if (session.user_id) {
          request.user = User.get(session.user_id)
        } else if (!actionName.equals("login")) {
          redirect(controller: "login", action: "login")
          return false
        }
      }
    }
  }
}

そして、すべてのコントローラー メソッドは、リクエスト オブジェクトのユーザー プロパティを読み取ることから始まります。

def actionName = {
   def user = request.user
   ...
}

上記のコードは機能しますが、すべてのコントローラー メソッドでコードが重複するのは避けたいと思います。フィルターがユーザー オブジェクトを "request.user" ではなく "user" という名前の変数にバインドして、すべてのコントローラーからアクセスできるようにすることは可能でしょうか?

これを不可能にするスコープの問題があるかもしれないことは理解していますが、Grails フレームワークは内部でかなりの魔法を作成できるように思われるので、質問する価値があるかもしれないと考えました。

4

3 に答える 3

1

コントローラーで beforeInterceptor を使用すると役立つ場合があります。

class LoginController {

    def user

    def beforeInterceptor = {
        user = request.user
    }

    def index = { 
        render text:"index: ${user}"        
    }

    def test = {
        render text:"test: ${user}"         
    }
}
于 2009-01-31T03:34:37.527 に答える
1

毎回ユーザーオブジェクトをリクエストオブジェクトに挿入するのは一般的には良い考えではないと思います:

リクエストの有効期間は非常に短いため、オブジェクトを取得するために http リクエストごとにキャッシュやさらに悪いことにデータベースへのラウンド トリップを行うことになり、不要な場合もあり、その後すぐに削除されます。そのため、必要に応じて、ID だけでなく、オブジェクト全体をセッションに保存することをお勧めします。

通常、ユーザーが認証されたときに true を返すメソッドと、AuthenticationServiceこのオブジェクトを返すメソッドを使用して を作成することをお勧めします。isLoggedIn()getLoggedInUser()

class AuthenticationService {
    def transactional = false
    boolean isLoggedIn() { return session.user_id }
    def getLoggedInUser() { return User.get(session.user_id) }
}

次に、認証されていない場合はリダイレクトにフィルターを使用し、ローカル参照を保存するためにインターセプターを使用する場合がありますuser = authenticationService.loggedInUser。しかし、これが最善の方法だとは思いません。AuthenticationAwareControllersrc/groovy のすべてのコントローラーの基本クラスとして抽象を作成し、次のような便利なメソッドを用意することをお勧めしますuser

class AuthenticationAwareController {
    def authenticationService
    def getUser() { return authenticationService.loggedInUser() }
}

このようにして、後で好きなようにユーザーを保存することについて考えを変えることができ、コードを変更する必要はありません。また、異なるセッション間で既に取得されたユーザー オブジェクト インスタンスを共有する Hibernate のキャッシュの恩恵を受けるため、db ラウンドトリップが回避されます。

取得したユーザー オブジェクトの有効性を確認するか、取得に失敗AuthenticationExceptionした場合は をスローする必要があります。(多分何かのようなAuthenticationService.getLoggedInUser(failOnError = false)。)

この Service/ControllerBase を小さなプラグインにして、すべてのアプリケーションで再利用することも、Spring セキュリティ プラグインを直接使用することもできます... ;-)

于 2010-12-08T17:52:52.203 に答える
0

あなたならできると思いますが、本当に苦労する価値はありますか?あなたの唯一の利点は、「request.user」ではなく「user」と入力することです。大きな利益ではありません。とにかく、ユーザーガイドの「12.7 実行時に動的メソッドを追加する」の指示に従っていただければと思います。動的メソッド「getUser() {return request.user}」を作成した場合、Groovy JavaBeans の getter/setter アクセスにより、必要な方法で「user」を簡単に参照できるようになると思います。

動的メソッドを追加する場合は、フィルターをスキップして動的メソッドですべてを実行することをお勧めします。

于 2009-02-01T07:01:24.457 に答える