简体   繁体   中英

Extending Authentication in Laravel 5.1

I have an application, similar to what hosting resellers get exept something different... this application is used on domainA.com and domainB.com. Both domains point at a single server, so both site run off single app exactly same files and single database.

When user accesses domainA.com we would see specific preferences for domainA ie logo and colour scheme. Same applies for domainB.com.

While both domains use single database, I want userA to be able to register on domainA and domainB with same email. When user is to try to login we would use something similar to: (taken from http://laravel.com/docs/master/authentication#authenticating-users )

Auth::attempt(['email' => $email, 'password' => $password, 'site' => 'domainA.com'])

This is functionality that I require is needed in order to keep data separate so that if you login as an adminA that belongs to domainA.com you would see what userA did on domainA.com and adminA wouldn NOT see what userA did on domainB.com. Same applies to adminB that belongs to domainB.com, adminB wouldn't be able to see what userA did on domainA.com.

I would like to know on how overall Authentication supplied with Laravel 5 be affected if I was to update default AuthController@create method with something similar to:

    protected function create(array $data)
    {        
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
            'site' => 'domainB.com'
        ]);
    }

I assume that password reminder can be easily updated, but because Laravel's authentication includes quite alot of built in functionality this might pose an issue unless after authentication user's identifier is used to identify user and to perform core functions


Update / this is where I am at

I have done following

  1. Remove unique condition in db for email in table users
  2. Updated login and register page to include extra param 'domain'
  3. Added new column 'domain' in users table - so now users belong to domains
  4. Middleware has to be created to find domain id from domains table on initial site access.
  5. in users table have to have email and domain_id set to unique to prevent duplications: UNIQUE INDEX unique_email_domain_id ( email , domain_id )
  6. Validation on register page need to be updated for email in function validator and replaced with something similar to 'unique:users,email,NULL,id,domain_id,1'

Also created a middle ware to create a global domain variable with data, below is an initial example:

<?php

namespace App\Http\Middleware;

use Closure;
use URL;

class DomainRouter
{
    /**
     * Handle an incoming request. Setting up domain for given session.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $domain= \App\Domain::where('domain', URL::to('/'))->firstOrFail();

        # config('domain')->id
        config([
            'domain' => $domain
        ]);

        return $next($request);
    }
}

Had to recreate login, register and forgot password by recreating the code, mainly copied over from core controllers

Site should be irrelevant to the database because there isn't a relationship at the db level between users and domains.

When user accesses domainA.com we would see specific preferences for domainA ie logo and colour scheme. Same applies for domainB.com.

While both domains use single database, I want userA to be able to register on domainA and domainB with same email.

Instead all you are doing is displaying different information or providing different functionality between domains.

What you should do instead is just extend the auth function/filter where when the user logs into a particular domain, you either identify the domain in which the current route exists before applying data/view/ability

ex:

MyController extends Controller
{

       public function view(ViewRepository $view)
    {

           return $view->make('path.to.my.view')
     }
}


}

Where ViewRepository extends View and overrides the data sent to the view based on the current routes domain.

You could get super fancy and pass in any domain specific repository file which acts as the interface/filter for any "core" functionality based on changes between the two domains... Only use this method for things that you need to act differently between the domains extending the core classes that you've developed to maintain DRY principles.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM