【问题标题】:Passing variables to a POST request from an outside controller从外部控制器将变量传递给 POST 请求
【发布时间】:2011-04-02 13:42:17
【问题描述】:

由于你们在我早期进入 Play 框架的过程中提供了非常大的帮助(感谢您),所以再次强调:

我们有一个有效的注册控制器,它将所有凭据发布到数据库。

但是,我们希望之后立即登录成为可能。下面是使这项工作的代码:

    public static void doRegistration(@Valid User user) {

//registering the user

    try{
        SecureController.authenticate(user.username, user.password, false, "MainController.index");
    }catch(Throwable ex){
        MainController.index();
    }

这很好用,但它不是非常安全,因为它会将所有凭据获取到服务器。我知道我必须以某种方式编辑我的 routes 文件,但我不知道如何。

路由文件:

*       /account                                SecureController.login
POST    /account/register                       RegistrationController.doRegistration
GET     /account/register                       SecureController.login

某处应该是 SecureController.authenticate 操作,但是我必须在 POST 之后的列中放入什么...它不能是 /account/register,因为它失败了...

先谢谢你!

【问题讨论】:

    标签: java post get playframework


    【解决方案1】:

    我不确定我是否理解您的问题。路由文件只是一种将您的 URL 配置为漂亮 URL 的方法。如果你不指定它们,那么它会使用默认的 {controller}/{method} 语法。

    您遇到的问题是,当您调用另一个控制器时,Play 会重定向到该控制器的方法,这涉及向您的浏览器发送一个请求,告诉它重定向(这可以确保应用程序的状态反映在浏览器中的 URL)。因此,重定向需要发送 GET 请求,并且包含在 GET 请求中的将是您的参数。

    【讨论】:

    • 感谢您的回答。实际上,我不希望 GET 重定向到对用户进行身份验证的控制器。有没有什么方法可以在不将所有参数放入 GET 变量中的情况下使用控制器执行代码?
    • Play 的理念是将所有业务逻辑放在你的模型中。如果您的 doRegister 方法想要执行一些特定的业务逻辑,那么只需在您的模型上调用所需的方法。如果这不可能,唯一的另一种方法是调用两个方法共享的非公共静态方法。非公共静态方法不被视为控制器中的操作,因此只需执行并将控制权返回给调用方法。这样您的控制器可以共享控制器逻辑。
    • 但是如果我在另一个控制器中工作,那么我需要从另一个控制器访问该控制器,这需要一个公共静态方法。除非我将所有功能都放在一个控制器中,但这不是正确的解决方案……目前我正在查看播放模块router,这有帮助吗?谢谢!
    【解决方案2】:

    正如您所说,您尝试做的事情并不安全。你应该做的(不是唯一的选择,只有一种可能)是:

    • 为用户维护当前的 doRegistration 操作
    • 创建一个服务类(不继承 Controller)。它可以是静态的或需要实例化(不过使用静态方法就足够了)。
    • 将@Before 方法添加到将始终执行的通用控制器。一种方法是使用@Before 方法创建一个控制器,并通过@With 注释将此控制器添加到所有其他控制器,以便始终为所有控制器执行@Before。它要求您为每个新控制器添加一个@With,但我相信它可以使代码保持干净。

    这个想法是控制器从服务类调用身份验证方法。这是一个简单的静态方法,此方法检查用户(如果已启用,是否拥有适当的许可等)并在会话中设置一些参数(通过 Session 对象)。

    为了帮助解决这个问题,您可能希望在用户中创建另一个身份验证方法,该方法返回要设置的属性(例如在 Map 中,如果它包含“错误”键,则由于某种原因无法对用户进行身份验证) .如何执行此步骤可以根据您的要求进行更改。

    设置会话后,您将重定向到您的选举页面(主页面、个人资料等)。由于您有通用的 @Before 方法,因此将执行此操作。此方法应验证会话中的凭据(用户身份验证、许可证类型等)并采取相应措施。您在 Play 的 Secure 控制器中有一个示例,但您可以创建自己的。

    这样,您可以从任何控制器使用服务的身份验证方法,允许通过多种方法进行身份验证,并使用一个公共点来验证会话。

    【讨论】:

    • 感谢您的广泛回答!但是我想知道,如果我实现了服务,那么如果服务无法扩展控制器(因此无法访问会话对象),我将如何编辑会话?我已经有了 Secure 模块,但我编辑了一些东西来自定义一些小行为。所以所有的逻辑都已经存在了......有什么理由在一个不从 Controller 扩展的类中实现 authenticate 方法吗? Controller.java 的源代码不可见 :( 谢谢!
    • Session 静态(注意大写的 S)使您无需从 Controller 继承即可访问会话...感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多