I like your answer, especially the separation between login and
authentication. I see it the same way and strive for the same abstractions.
But I don't like the idea of using an exception for failed
authentication. I am not strong on this point but I learned (and adhere
to it) that execution flows should be very rarely guided by throw/catch
interactions. Exceptions are called exceptions because, well, they are
an exception of the regular control flow.
A failing authentication attempt is probably not so rare in an web
application, or is it?
The definition of exception is very application and context specific,
but in this case I feel slightly disquiet.
Any thoughts on that?
Cheers
Jakob
On 09/05/2014 08:59 PM, Gareth Wedley wrote:
> Ive struggled with this one too.
>
> One thing I would say is do you mean login() or do you mean authenticate()?
> Login to me assumes that something is managing some sort of user session. I
> could be wrong, but I feel session management falls into the delivery
> mechanism layer. For example if you had a RESTful web service, you would
> have to authenticate every request. If you had a more traditional web
> application, you'd manage it in a cookie. Either way, it depends on the
> delivery mechanism not the application.
>
> What the application can offer you is an interactor to authenticate a user.
> Lets call it AuthenticateUserInteractor
>
> Think about the command pattern that is applied to the interactors. We will
> have a method execute() on AuthenticateUserInteractor. If the user is
> authenticated, the interactor can call some method on the presenter
> interface, something like authenticateUserSuccess(Response), and the
> execute() method returns null. This is an example of Command Query
> Separation. We commanded the class to do something. If it succeeds we
> expect it to return nothing.
>
> What about the case where a user fails authentication? Thinking about
> Command Query Separation, if we command the interactor to do something and
> it fails to carry out the command we should do the same thing that most
> code does if it fails - throw an exception. The interactor can throw a
> FailedToAuthenticateUserException.
>
> You can then wrap the call to the interactor in a try/catch.
>
>
> On Friday, 5 September 2014 07:20:50 UTC+1, Christian B wrote:
>>
>> Hey guys,
>>
>> Im trying to "login" with clean architecture, but im having some trouble.
>>
>> <?php
>>
>> // PSEUDO CODE
>>
>> class LoginController {
>> public function loginAction() {
>>
>> // Get the login form
>> $form = FormFactory::factory('LoginForm');
>>
>> // Validate the form
>> if ($form->isValid($this->getRequest()->getParams()) {
>>
>> // Do the login
>> $interactor = LoginInteractorFactory::factory();
>> $interactor->login($form->getValue('username'), $form->
>> getValue('password');
>>
>> // OK so here is my question, *who does the redirect*? In
>> clean arch there is no return value on the interactor
>> // I have a presenter, but the Controller does not know about
>> the presenter.
>> }
>> }
>> }
>>
>> What i thought was, i could set the LoginController instance as a Context
>> in the interactor so the interactor would do something like
>>
>> <?php
>>
>> class LoginInteractor {
>>
>> private $context;
>>
>> public function login($username, $password) {
>> $result = $this->authService->login($username, $password);
>>
>> // The Context would be the Controller, which implements
>> loginSuccessful as the redirect, good idea?????
>> if ($result) $this->context->loginSuccessful();
>>
>> }
>> }
>>
>>
>>
>>
>>
>>
>
--
Jakob Holderbaum, M.Sc.
Systems Engineer
0176 637 297 71
http://jakob.io
h...@jakob.io
#hldrbm