ServiceStack中的注册后操作

时间:2015-03-12 19:10:42

标签: .net authentication servicestack ormlite-servicestack

我已经将ServiceStack用于一些项目并且非常喜欢它。也就是说,这是我第一次尝试以任何方式处理用户身份验证,所以请原谅我,如果我在这里理解或实施中出现任何根本性错误。

我需要能够跟踪用户的自定义属性,例如用户类型和与之关联的公司。为此,我创建了一个单独的用户"包含我要跟踪的用户的详细信息以及自定义位的类。我喜欢这个,因为,例如,我可以将UserTypeId存储为User的属性,[Reference]实际的UserType对象。这样我就可以使用服务代码中的其他地方的LoadReferences将嵌套数据发送回客户端。

为了做到这一点,我需要将自定义User对象发送回浏览器(它是一个Web应用程序)。到目前为止,我已经实现了一个CustomCredentialsAuthProvider,它将User对象添加到AuthResponse,如下所示:

public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
    {
        //let normal authentication happen
        var authResponse = (AuthenticateResponse)base.Authenticate(authService, session, request);

        using (var db = authService.TryResolve<IDbConnectionFactory>().OpenDbConnection())
        {
            User user = db.LoadSingleById<User>(int.Parse(authResponse.UserId));

            //return your own class, but take neccessary data from AuthResponse
            return new
            {
                SessionId = authResponse.SessionId,
                ReferrerUrl = authResponse.ReferrerUrl,
                ResponseStatus = authResponse.ResponseStatus,
                UserSession = user
            };
        }
    }

这很有效。要在应用程序中处理用户配置文件管理,我发布任何所需的更新,这些更新将写入User表和IUserAuthRepository(两者都使用当前会话UserAuthId作为键)。

好的,那是所有的基础。我现在需要做的是,如果可能的话,允许用户A注册另一个用户B而不将其会话切换到用户B.据我所知,Register方法只返回刚刚创建的用户ID ...

{"userId":"1019","responseStatus":{}}

...并且还将会话cookie设置为新创建的用户会话。我想我需要一种方法来阻止这种自动会话分配,并且能够只注册新用户并独立获取其他ID。这可能吗?

在相关说明中,我希望能够在注册后立即检索整个用户个人资料,而不仅仅是&#34; userId&#34;。就目前而言,我需要立即进行另一次服务器调用以获取用户详细信息(根据session.UserAuthId从用户中提取)。

提前致谢!

1 个答案:

答案 0 :(得分:1)

自定义验证服务响应

我建议您始终返回ServiceStack Services中的具体类(即代替匿名对象),这有助于为DTO类型生成元数据服务,并允许您对类型化API中的响应进行反序列化。

您还应该考虑遵守Authenticate服务合同(所有客户都期望)并继续返回AuthenticateResponse类型。您可以使用Dictionary<string,string> Meta属性将其他元数据附加到返回类型,例如:

var r = (AuthenticateResponse)base.Authenticate(authService, session, request);

using (var db = authService.TryResolve<IDbConnectionFactory>().Open())
{
    User user = db.LoadSingleById<User>(int.Parse(r.UserId));

    r.Meta = new Dictionary<String,String> {
        {"customId", user.CustomId},
        //etc
    };

    return r;
}

如果您选择返回其他类型,您的服务仍然有用,但这样就不会破坏期望收到键入的AuthenticateResponse的.NET服务客户端。

自定义注册实施

对于自定义注册而不是使用现有的RegisterService实现,请复制并创建自己的版本,以执行您想要的操作。

注册服务使用IAuthRepository依赖关系来创建新用户:

public IAuthRepository AuthRepo { get; set; }

它转换为IUserAuthRepository,以便它可以访问更丰富的API,例如:

var userAuthRepo = AuthRepo.AsUserAuthRepository(GetResolver());

在这里,您可以通过填充UserAuth类的实例来注册新用户,例如:

var newUserAuth = request.ConvertTo<UserAuth>();
newUserAuth.PrimaryEmail = request.Email;

您可以使用以下内容创建新用户:

userAuthRepo.CreateUserAuth(newUserAuth, request.Password)

只会将新的UserAuth信息保留在已注册的IUserAuthRepository

由于您现在正在使用自己的Register类实现,因此它不会影响您现有的Session,您可以返回您喜欢的任何响应。