2

我正在使用NancyFx制作一个简单的网站,用户可以使用 ajax 控件登录和退出。

我已经阅读了有关Nancy 表单身份验证的文档,并且我认为我已经完成了所有必需的步骤。

  1. 安装 Nancy.Authentication.Forms 包
  2. 实现 IUserMapper
  3. 实现路由来处理登录和注销
  4. 配置和启用表单身份验证

我遇到一个问题,在调用登录后,请求没有当前用户集。执行登录后,我可以看到一个 cookie 集。然而,用户映射器没有被调用。我尝试使用和不使用 this.RequiresAuthentication(); 请求路由 仍然没有用户。

这是我的第 4 步的引导程序实现

public class Bootstrapper : DefaultNancyBootstrapper
{
    protected override void ConfigureApplicationContainer(TinyIoCContainer container)
    {
        container.Register<ISessionFactory>((c, p) => SessionFactory.Factory);
    }

    protected override void ConfigureConventions(NancyConventions conventions)
    {
        base.ConfigureConventions(conventions);

        conventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("assets", @"content/assets"));
        conventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("application", @"content/application"));
    }

    protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
    {
        base.ConfigureRequestContainer(container, context);
        container.Register<IUserMapper, UserMapper>();
    }

    protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
    {
        base.RequestStartup(container, pipelines, context);

        var formsAuthConfiguration =
            new FormsAuthenticationConfiguration()
            {
                RedirectUrl = "~/",
                UserMapper = container.Resolve<IUserMapper>()
            };

        FormsAuthentication.Enable(pipelines, formsAuthConfiguration);
    }
}

这是我第 3 步的登录和注销逻辑。

Post["/login"] = x =>
        {
            //Verify here, hardcode for testing
            string email = "test@example.com";

            User user = ExecuteCommand(new FetchUser(email));

            this.LoginWithoutRedirect(user.Session);
            return new { email = user.Email, authorized = true, status = "okay" };
        };

        Post["/logout"] = x =>
        {
            return this.Logout("~/");
        };

我的 IUsermapper 只是从具有给定 ID 的数据库中查找用户。我可以看到它是在 RequestStartup 解析 IUserMapper 时构建的,但是从来没有对 getUserFromIdentifier 函数进行任何调用。

任何帮助都会很棒。

4

1 回答 1

1

GetUserFromIdentifier方法没有被调用,因为您正在使用LoginWithoutRedirect扩展。调用的不是登录,GetUserFromIdentifier而是任何后续重定向。

更常见的做事方式是:

string email = "test@example.com";
User user = ExecuteCommand(new FetchUser(email));
this.LoginAndRedirect(user.Session);

预计不会直接访问登录路由。相反,用户通常会请求受保护的资源,经过身份验证,然后重定向到请求的资源。

其他几点:

当我尝试您的代码时,我收到返回匿名类型的错误。相反,我需要将类型返回为 json,如下所示:

this.LoginWithoutRedirect(user.Session);
return Response.AsJson(new
{
    email = user.Email,
    authorized = true,
    status = "okay"
});

这工作正常,它登录并将您的匿名类型作为 json 对象返回,并且由于没有重定向,因此正如预期的那样,它不会调用GetUserFromIdentifier.

最后,您的/logout路线应该使用this.RequiresAuthentication(). 这是有道理的,因为只有经过身份验证的用户才需要注销。它还会在 GetUserFromIdentifier返回 null 时保护您 - 可能是因为缓存的用户已超时。RequiresAuthentication检测到此空用户并重定向回Get["/login"].

于 2013-06-04T15:27:22.427 回答