1

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?

2 Answers 2

3

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;
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

That solves 1 problem, however the password is hashed differently than the laravel default, I must admit though the connection in the model is a pretty nifty feature
I've added more info on the hashing part of the question.
The cleanest method is using the HashServiceProvider as @Andrius mentioned. Good idea.
Can't seem to get the connection or table to read from the User model it just defaults
But you specified the second connection in your database.php and added ` protected $connection = '<NEW CONNECTION NAME>';` in your model?
0

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; 
    });

    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.