2

用户登录功能对于许多应用程序来说非常常见。我想看看人们如何以面向对象的方式实现此功能。

我有一个用户,我需要针对系统验证用户 ID 和密码(这可能是 ldap、数据库等)。那么你会创建什么样的类和操作来实现这个功能呢?

或者 OO 是不是开发这个功能的坏选择?

我即将开始一个新项目,所以想收集好的选择。


我知道已经有提供此解决方案的框架。我在早期的项目中使用过它们。我试图看到的是人们如何以 OO 方式实现这一点。

我阅读了答案,每个人都建议使用单独的凭据和身份验证服务。如果我使用类名而不是凭据作为用户,那么用户类不应该有一个名为登录的方法吗?就像 Person 对象将有一个方法喝而不是 DrinkService 或者我正确理解这一点是错误的?

4

5 回答 5

3

它到底需要有多大的可扩展性?我将定义一个抽象类 Credentials,它封装了给定系统所需的身份验证信息。将其子类化为特定系统类型。一个示例是仅包含用户名和密码的 BasicCredentials。然后,定义一个定义身份验证方法的接口。也许我还会定义一个包含附加主机信息的抽象主机类。这可能过于抽象,具体取决于您设想的身份验证对象。

此示例代码是 C# 3.0。

public abstract class Credentials
{
}

public class BasicCredentials : Credentials
{
    public String Username { get; set; }
    public String Password { get; set; }
}

public abstract class Host
{
}

public class IPHost : Host
{
    public IPAddress Location { get; set; }
}

public interface IAuthenticate
{
    bool Authenticate(Credentials creds, Host host);
}

public class BasicAuthenticator : IAuthenticate
{
    public bool Authenticate(Credentials creds, Host host)
    {
        // Check to make sure we're given the right type of parameters
        if (creds is BasicCredentials && host is IPHost)
        {
            // Do your magic here
        }
    }
}
于 2009-02-18T11:25:07.553 回答
3

或者 OO 是不是开发这个功能的坏选择?

我认为 OO 的使用不会以任何方式限制您,所以问题应该是,我可以负担得起用 OO 构建这部分吗?其他样式可能会快很多。

话虽如此,我将创建以下类:

  • 证书
  • 身份验证服务

此外,类 User 需要一个 getCredentials() 函数。但是,这种方法意味着您始终使用用户名/密码进行身份验证。对于更广泛的方法,让 AuthenticationService 对 User 对象本身进行操作。

于 2009-02-18T11:33:12.120 回答
2

如果你想要一个 OO 解决方案,我会选择使用 OO 语言并编写一些类;-)。

但说真的,在基本级别上,您将需要一个数据bean 来存储登录信息,我们称之为“登录”。然后我会选择提供身份验证的服务,我们称之为“AuthenticationService”。最后,您可以提供所需的每种不同类型的身份验证方案的具体实现。所以你会有类似的东西:

public class Login {
    private String loginName;
    private String password;

    /* getters / setters */
}

public interface AuthenticationService {
    public boolean isLoginValid(Login login);
}

public class LdapAuthenticationService implements AuthenticationService {
    public boolean isLoginValid(Login login) {
        /* LDAP specifics here */
    }
}

public class DatabaseAuthenticationService implements AuthenticationService {
    public boolean isLoginValid(Login login) {
        /* database specifics here */
    }
}

根据您当前的需求,使用依赖注入将所需的具体实现添加到您的系统中。

于 2009-02-18T11:25:22.590 回答
0

面向对象的方法是使用提供的类或找到一个库并将其子类化,如果它还没有做你想要的:)

于 2009-02-18T11:32:42.603 回答
0

身份验证还涉及检索凭据,您需要在身份验证框架中包括如何访问凭据。这可能比已经突出显示的 Authenticator 类更重要。

class CredentialsAccessor {
  public bool hasCredentials(){};
  public Credentials getCredentials();
}
class FormAccessor : CredentialsAccessor {
    // get credentials from a webapp or form
}
class CookieAccessor : CredentialsAccessor {
    // get credentials based on cookie
}
class SessionAccessor : CredentialsAccessor {
    // get credentials from user session
}
class CredentialAccessManager 
{
   list<CredentialsAccessor> m_Credentials;

   Credentials getCredentials() 
   {
     foreach( CredentialsAccessor l_accessor in m_Credentials )
     {
         if( l_accessor.hasCredentials() ) return l_accessor.credentials();
     }
   }
}

您以正确的顺序将所有访问器对象插入列表中,您的用户每次都会神奇地登录。

于 2009-02-18T23:53:48.657 回答