Ian
Ian

Reputation: 3676

Extending laravel 5.2 authentication

I am trying to connect Laravel to an external database for the authentication, though I am not sure how to go about it.

How would I go about extending Laravels authentication to allow for a custom login method?

The database is auth and it uses username or email to login with, the password hash is sha512.

What would be the best way?

Upvotes: 1

Views: 157

Answers (2)

Andrius
Andrius

Reputation: 5939

Different database:

I would say that the best way to do so is to define a separate connection for the specific model.

So, in your database.php config, add another connection (let's name it mysql_auth).

To use it in a model, you need to add this as a variable in the class:

protected $connection = 'mysql_auth';

Now, by default the model queries will do queries to that exact connection.

Just as a note, to build migrations, use Schema::connection('mysql_auth')->create(...).

Different hashing method:

Original: To use different hashing functionality, you need to, basically, use a different class as a Hash class.

By default, hashing, as defined in providers, is done here: Illuminate\Hashing\HashServiceProvider::class. To change it, you'll have to create a separate, different class as a provider and change this line:

$this->app->singleton('hash', function () {
    return new BcryptHasher;
});

Now, this will then link to your hashing class (that will implement HasherContract interface) that will do the sha512 (or whatever else) hashing.

All in all, check out Illuminate\Hashing\HashServiceProvider, how it registers the hashing methods and Illuminate\Hashing\BcryptHasher for the methods that you need to implement to implement your hashing.

Update:

Comment out Illuminate\Hashing\HashServiceProvider::class in providers and add something like \App\Providers\NewHashServiceProvider::class. Now, we create a new provider(app/Providers). This should work:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class NewHashServiceProvider extends ServiceProvider
{
    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('hash', function () {
            return new \App\ShaHasher;
        });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return ['hash'];
    }
}

This actually returns our hasher, that we will create in a moment.

To implement ShaHasher, create a class that implements HasherContract (just like BcryptHasher does):

<?php

namespace App;

use RuntimeException;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;

class ShaHasher implements HasherContract
{
    /**
     * Hash the given value.
     *
     * @param  string  $value
     * @param  array   $options
     * @return string
     *
     * @throws \RuntimeException
     */
    public function make($value, array $options = [])
    {
        return hash('sha512',$value);
    }

    /**
     * Check the given plain value against a hash.
     *
     * @param  string  $value
     * @param  string  $hashedValue
     * @param  array   $options
     * @return bool
     */
    public function check($value, $hashedValue, array $options = [])
    {
        if (strlen($hashedValue) === 0) {
            return false;
        }

        return hash('sha512',$value) == $hashedValue
    }

    /**
     * Check if the given hash has been hashed using the given options.
     *
     * @param  string  $hashedValue
     * @param  array   $options
     * @return bool
     */
    public function needsRehash($hashedValue, array $options = [])
    {
        return false;
    }
}

Upvotes: 3

codedge
codedge

Reputation: 5164

The new implementation for Sha512 would then probably be something like:

namespace App;

use Illuminate\Contracts\Hashing\Hasher;

class Sha512Hasher implements Hasher
{
    public function make($value, array $options = [])
    {

    }

    public function check($value, $hashedValue, array $options = [])
    {

    }

    public function needsRehash($hashedValue, array $options = [])
    {

    }
}

So you basically utilizing a ServiceContract Illuminate\Contracts\Hashing\Hasher

To bind this use a ServiceProvider:

class Sha512ServiceProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('hash', function () { 
        return new App\Sha512Hasher; 
    });

    }
}

Upvotes: 0

Related Questions