Re: Laravel / Spark and their token authentication system

A few days ago I wrote a rather lengthy article about how I modified Spark’s built in token authentication system by extending / replacing some of the classes, adding columns to the table it created, and renaming things.

I haven’t had much time to actually implement the authentication part itself because WordCamp London happened over the weekend.

One of the talks I saw was by Alain Schlesser about how modern PHP engineering principles using object oriented code can fit into WordPress’s notoriously procedural structure. It was eye opening.

Later I also had the privilege of having a rather lengthy conversation about what Object Oriented Programming is and why what I’ve done might not have been the best of solutions. Go check out his blog, it’s immensely useful for levelling up your PHP skills.

Starting again

Basically the crux of the issue is that I broke the contracts by modifying some of the classes / abstracts / bypassed the Spark User. The reason the abstract methods are typehinted is because they give guarantees for the code that builds upon that that things will work in a certain way. If I change that, I risk introducing horrendous bugs into the site at a later point which is going to be a pain to untangle, and then what’s the point of object-oriented anyways?

So, instead of modifying the current implementation of TokenGuard and everything that serves that (TokenRepository, Token, HasApiTokens), I’ll create an entirely new one that will still be heavily influenced (read: mostly copy-pasted) by those, but it will live independently.

I can then detach Spark’s token authentication by changing the driver in config/auth.php from spark to something else, because the whole Token authentication only kicks in if the request is via the spark driver. That’s defined in SparkServiceProvider, and the viaRequest is in AuthManager.

The only thing that I won’t be able to “unhook” is the HasApiTokens trait on the User class, because that’s imported regardless of what the driver is.

That also means that I need to use a different method name than setToken because HasApiTokens’s method looks like this:

// /spark/src/HasApiTokens.php
...
public function setToken(Token $token)
{
    $this->currentToken = $token;

    return $this;
}
...

It’s typehinted, and I can’t redeclare a method with the same name with a different signature because PHP is going to be cross with me.

I also can’t declare a class with the same name that Spark already has because conflicts.

Luckily the only things calling setToken on User are Spark’s TokenGuard, though I wonder how to handle a situation where something else expects the default guard to be there, but I replaced it.

As a final note, tomorrow’s reading will start with Laravel’s documentation on packages, because if I’m going to create a custom guard, then I’m going to do it Properly©!