I have the following policy called UserPolicy.
I want only admin users to access/edit the users data, even though I have set the return value to true(for testing) I still get 403 response no matter what.
namespace App\Policies;
use App\Models\Auth\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class UserPolicy
{
use HandlesAuthorization;
public function viewAny(User $user)
{
// return $user->admin();
return true;
}
}
I have registered the policy as follows
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use App\Models\Auth\User;
use App\Policies\UserPolicy;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
User::class => UserPolicy::class,
];
/**
* Register any authentication / authorization services.
*
* #return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
The following code is how I use it in the controller
if (Gate::denies('viewAny')) {
return response('Not Authorized!', 403);
}
You should use authorize() method in your controller and pass User class as the second parameter. It will point the request to the targeted policy.
authorize() method is by default provided by Illuminate\Foundation\Auth\Access\AuthorizesRequests trait in your base controller.
Your controller could be like below:
try {
$this->authorize('viewAny', User::class);
} catch (AuthorizationException $e) {
return response('Not Authorized!', 403);
}
I create a policy called LetterPolicy , this is the code
namespace App\Policies;
use App\Letter;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class LetterPolicy
{
use HandlesAuthorization;
/**
* Create a new policy instance.
*
* #return void
*/
public function __construct()
{
//
}
public function update(User $user, Letter $letter)
{
return($user->id === $letter->user_id || $user->role_id===1 ) ;
}
}
and this is authserviceprovider
namespace App\Providers;
use App\Letter;
use App\Policies\LetterPolicy;
use App\Policies\UserPolicy;
use App\User;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
User::class => UserPolicy::class,
Letter::class => LetterPolicy::class,
];
/**
* Register any authentication / authorization services.
*
* #return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
And in the following code I check for the user
class LetterController extends Controller
{
protected $user;
public function __construct()
{
$this->middleware(function ($request, $next){
$this->user = Auth::user();
return $next($request);
});
}
public function edit(Letter $letter)
{
if($this->user->can('update', $letter)){
//edit
}
else
abort('403', 'Access Denied');
}
The code is working well in localhost but on the remote server it reports the access denied error. I created this policy after deploying the site on the server so I create a route /clear-cache with code
Route::get('/clear-cache', function() {
$exitCode = \Illuminate\Support\Facades\Artisan::call('cache:clear');
});
To clear the cache after creating the policy. But it still reports the 403 error. What is the problem?
I tried dd($this->user->id === $letter->user_id || $this->user->role_id===1 ); in the COntroller and it returned false. I tried dd($this->user->id == $letter->user_id || $this->user->role_id==1 ); and it was true. Now it works but I don't know why!!!
Fjarlaegur's answer was the key. I had the same problem: in localhost there was no issue, but in production server somehow every authorization failed and it was because of the comparison operator. Changed from === to == and all as good.
I am trying to do a role based permission control in a Laravel application. I want to check what actions can some user do, but i can't figure out how to implement gates and policies in my model (the permission description is in the database and are booleans asociated to a table that stores the resource's ids).
This is the database model that im using:
I would like to know if laravel gates is useful in my case, and how can i implement it, if not, how to make a basic middleware that take care of permission control to protect routes (or controllers).
In the table resource i have a uuid that identifies the resources, the alias is the name of the resource and has dot notation values of actions or context of the resource (eg. 'mysystem.users.create', 'mysystem.roles.delete', 'mysystem.users.images.view'). The policy tables has a boolean 'allow' field that describes the permission of users.
Thanks in advance.
This is the way that I implement role based permissions in Laravel using Policies.
Users can have multiple roles.
Roles have associated permissions.
Each permission allows a specific action on a specific model.
Migrations
Roles table
class CreateRolesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->string('label');
$table->text('description');
$table->timestamps();
});
}
// rest of migration file
Permissions table
class CreatePermissionsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('permissions', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->string('label');
$table->text('description');
$table->timestamps();
});
}
// rest of migration file
Permission Role Pivot Table
class CreatePermissionRolePivotTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('permission_role', function (Blueprint $table) {
$table->integer('permission_id')->unsigned()->index();
$table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
$table->integer('role_id')->unsigned()->index();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->primary(['permission_id', 'role_id']);
});
}
// rest of migration file
Role User Pivot Table
class CreateRoleUserPivotTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->integer('role_id')->unsigned()->index();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->primary(['role_id', 'user_id']);
});
}
// rest of migration file
Models
User
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function assignRole(Role $role)
{
return $this->roles()->save($role);
}
public function hasRole($role)
{
if (is_string($role)) {
return $this->roles->contains('name', $role);
}
return !! $role->intersect($this->roles)->count();
}
Role
class Role extends Model
{
protected $guarded = ['id'];
protected $fillable = array('name', 'label', 'description');
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
public function givePermissionTo(Permission $permission)
{
return $this->permissions()->save($permission);
}
/**
* Determine if the user may perform the given permission.
*
* #param Permission $permission
* #return boolean
*/
public function hasPermission(Permission $permission, User $user)
{
return $this->hasRole($permission->roles);
}
/**
* Determine if the role has the given permission.
*
* #param mixed $permission
* #return boolean
*/
public function inRole($permission)
{
if (is_string($permission)) {
return $this->permissions->contains('name', $permission);
}
return !! $permission->intersect($this->permissions)->count();
}
}
Permission
class Permission extends Model
{
protected $guarded = ['id'];
protected $fillable = array('name', 'label', 'description');
public function roles()
{
return $this->belongsToMany(Role::class);
}
/**
* Determine if the permission belongs to the role.
*
* #param mixed $role
* #return boolean
*/
public function inRole($role)
{
if (is_string($role)) {
return $this->roles->contains('name', $role);
}
return !! $role->intersect($this->roles)->count();
}
}
Policies
A policy is required for each model. Here is an example policy for a model item. The policy defines the 'rules' for the four actions 'view, create, update, delete.
class ItemPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view the item.
*
* #param \App\User $user
* #return mixed
*/
public function view(User $user)
{
$permission = Permission::where('name', 'items-view')->first();
return $user->hasRole($permission->roles);
}
/**
* Determine whether the user can create items.
*
* #param \App\User $user
* #return mixed
*/
public function create(User $user)
{
$permission = Permission::where('name', 'items-create')->first();
return $user->hasRole($permission->roles);
}
/**
* Determine whether the user can update the item.
*
* #param \App\User $user
* #return mixed
*/
public function update(User $user)
{
$permission = Permission::where('name', 'items-update')->first();
return $user->hasRole($permission->roles);
}
/**
* Determine whether the user can delete the item.
*
* #param \App\User $user
* #return mixed
*/
public function delete(User $user)
{
$permission = Permission::where('name', 'items-delete')->first();
return $user->hasRole($permission->roles);
}
}
Register each policy in AuthServiceProvider.php
use App\Item;
use App\Policies\ItemPolicy;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
Item::class => ItemPolicy::class,
];
// rest of file
Controllers
In each controller, refer to the corresponding authorisation action from the policy.
For example, in the index method of ItemController:
public function index()
{
$this->authorize('view', Item::class);
$items = Item::orderBy('name', 'asc')->get();
return view('items', ['items' => $items]);
}
Views
In your views, you can check if the user has a specific role:
#if (Auth::user()->hasRole('item-administrator'))
// do stuff
#endif
or if a specific permission is required:
#can('create', App\User::class)
// do stuff
#endcan
Answer for your Question:how to make a basic middleware that take care of permission control to protect routes (or controllers)?.
Just an Example:
Here is the simple role middleware for your routes
AdminRole
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class AdminRole
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::user()->role->name!=="admin"){ //Check your users' role or permission, in my case only admin role for routes
return redirect('/access-denied');
}
return $next($request);
}
}
After defining this middleware
Update your kernel.php file as
protected $routeMiddleware = [
..............
'admin' =>\App\Http\Middleware\AdminRole::class,
...................
];
And to use this route middleware:
There are different way to use route middleware but following is one example
Route::group(['middleware' => ['auth','admin']], function () {
Route::get('/', 'AdminController#index')->name('admin');
});
Note: There are some tools and libraries for roles and permission on laravel but above is the example of creating basic route middle-ware.
Because the laravel model did not fit my database so much, I did almost everything again. This is a functional draft in which some functions are missing, the code is not optimized and it may be a bit dirty, but here it is:
proyect/app/Components/Contracts/Gate.php This interface is used to create singleton in AuthServiceProvider.
<?php
namespace App\Components\Contracts;
interface Gate
{
public function check($resources, $arguments = []);
public function authorize($resource, $arguments = []);
}
proyect/app/Components/Security/Gate.php This file loads the permissions from the database. This could be improved a lot :(
<?php
namespace App\Components\Security;
use App\Components\Contracts\Gate as GateContract;
use App\Models\Security\Resource;
use App\Models\Security\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
class Gate implements GateContract
{
use HandlesAuthorization;
protected $container;
protected $userResolver;
protected $policies = [];
public function __construct(Container $container, callable $userResolver)
{
$this->container = $container;
$this->userResolver = $userResolver;
}
public function permissionsForUser(User $user)
{
$result = User::with(['roles.resources', 'groups.resources', 'policies'])->where('id', $user->id)->first();
$list = [];
//role-specific ... the order is important role < group < user permissions
foreach ($result->roles as $role) {
foreach ($role->resources as $permission) {
if (isset($list[$permission->uuid])) {
if ($list[$permission->uuid]['on'] == User::ROLE_POLICY) {
if ($permission->pivot->allow == false) {
$list[$permission->uuid]['allow'] = false;
}
} else {
$list[$permission->uuid]['allow'] = $permission->pivot->allow ? true : false;
$list[$permission->uuid]['on'] = User::ROLE_POLICY;
$list[$permission->uuid]['id'] = $role->id;
}
} else {
$list[$permission->uuid] = [
'allow' => ($permission->pivot->allow ? true : false),
'on' => User::ROLE_POLICY,
'id' => $role->id];
}
}
}
// group-specific
foreach ($result->groups as $group) {
foreach ($group->resources as $permission) {
if (isset($list[$permission->uuid])) {
if ($list[$permission->uuid]['on'] == User::GROUP_POLICY) {
if ($permission->pivot->allow == false) {
$list[$permission->uuid]['allow'] = false;
}
} else {
$list[$permission->uuid]['allow'] = $permission->pivot->allow ? true : false;
$list[$permission->uuid]['on'] = User::GROUP_POLICY;
$list[$permission->uuid]['id'] = $group->id;
}
} else {
$list[$permission->uuid] = [
'allow' => ($permission->pivot->allow ? true : false),
'on' => User::GROUP_POLICY,
'id' => $group->id];
}
}
}
// user-specific policies
foreach ($result->policies as $permission) {
if (isset($list[$permission->uuid])) {
if ($list[$permission->uuid]['on'] == User::USER_POLICY) {
if ($permission->pivot->allow == false) {
$list[$permission->uuid]['allow'] = false;
}
} else {
$list[$permission->uuid]['allow'] = $permission->pivot->allow ? true : false;
$list[$permission->uuid]['on'] = User::USER_POLICY;
$list[$permission->uuid]['id'] = $result->id;
}
} else {
$list[$permission->uuid] = [
'allow' => ($permission->pivot->allow ? true : false),
'on' => User::USER_POLICY,
'id' => $result->id,
];
}
}
return $list;
}
public function check($resources, $arguments = [])
{
$user = $this->resolveUser();
return collect($resources)->every(function ($resource) use ($user, $arguments) {
return $this->raw($user, $resource, $arguments);
});
}
protected function raw(User $user, $resource, $arguments = [])
{
$list = $user->getPermissionList();
if (!Resource::isUUID($resource)) {
if (empty($resource = Resource::byAlias($resource))) {
return false;
}
}
if (empty($list[$resource->uuid]['allow'])) {
return false;
} else {
return $list[$resource->uuid]['allow'];
}
}
public function authorize($resource, $arguments = [])
{
$theUser = $this->resolveUser();
return $this->raw($this->resolveUser(), $resource, $arguments) ? $this->allow() : $this->deny();
}
protected function resolveUser()
{
return call_user_func($this->userResolver);
}
}
proyect/app/Traits/Security/AuthorizesRequests.php This file is added to controller. Allows to use $this->authorize('stuff'); in a controller when is added.
<?php
namespace App\Traits\Security;
use App\Components\Contracts\Gate;
trait AuthorizesRequests
{
public function authorize($ability, $arguments = [])
{
list($ability, $arguments) = $this->parseAbilityAndArguments($ability, $arguments);
return app(Gate::class)->authorize($ability, $arguments);
}
}
proyect/app/Providers/AuthServiceProvider.php This file is the same that can be found on proyect/vendor/laravel/framework/src/Illuminate/Auth/AuthServiceProvider.php, but i changed some parts to add new classe. Here are the important methods:
<?php
namespace App\Providers;
use App\Components\Contracts\Gate as GateContract;
use App\Components\Security\Gate;
use Illuminate\Auth\AuthManager;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/* function register() ... */
/* other methods () */
protected function registerAccessGate()
{
$this->app->singleton(GateContract::class, function ($app) {
return new Gate($app, function () use ($app) {
return call_user_func($app['auth']->userResolver());
});
});
}
/* ... */
}
proyect /app/Http/Middleware/AuthorizeRequest.php This file is used to allow add the 'can' middleware to routes, eg: Route::get('users/', 'Security\UserController#index')->name('users.index')->middleware('can:inet.user.list');
<?php
namespace App\Http\Middleware;
use App\Components\Contracts\Gate;
use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;
class AuthorizeRequest
{
protected $auth;
protected $gate;
public function __construct(Auth $auth, Gate $gate)
{
$this->auth = $auth;
$this->gate = $gate;
}
public function handle($request, Closure $next, $resource, ...$params)
{
$this->auth->authenticate();
$this->gate->authorize($resource, $params);
return $next($request);
}
}
but you must overwrite the default value in proyect/app/Http/Kernel.php:
/* ... */
protected $routeMiddleware = [
'can' => \App\Http\Middleware\AuthorizeRequest::class,
/* ... */
];
To use #can('inet.user.list') in a blade template you have to add this lines to proyect/app/Providers/AppServiceProvider.php:
class AppServiceProvider extends ServiceProvider
{
public function boot()
Blade::if ('can', function ($resource, ...$params) {
return app(\App\Components\Contracts\Gate::class)->check($resource, $params);
});
}
/* ... */
User model at proyect/app/Models/Security/User.php
<?php
namespace App\Models\Security;
use App\Components\Contracts\Gate as GateContract;
use App\Models\Security\Group;
use App\Models\Security\Resource;
use App\Models\Security\Role;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
class User extends Authenticatable
{
use SoftDeletes;
use Notifiable;
public $table = 'user';
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
// tipos de politicas
const GROUP_POLICY = 'group_policy';
const ROLE_POLICY = 'role_policy';
const USER_POLICY = 'user_policy';
protected $dates = ['deleted_at'];
public $fillable = [
];
public function policies()
{
return $this->belongsToMany(Resource::class, 'user_policy', 'user_id', 'resource_id')
->whereNull('user_policy.deleted_at')
->withPivot('allow')
->withTimestamps();
}
public function groups()
{
return $this->belongsToMany(Group::class, 'user_group', 'user_id', 'group_id')
->whereNull('user_group.deleted_at')
->withTimestamps();
}
public function roles()
{
return $this->belongsToMany(Role::class, 'user_role', 'user_id', 'role_id')
->whereNull('user_role.deleted_at')
->withTimestamps();
}
public function getPermissionList()
{
return app(GateContract::class)->permissionsForUser($this);
}
}
Group model at proyect/app/Models/Security/Group.php THis is the same than Role, change only names
<?php
namespace App\Models\Security;
use App\Models\Security\Resource;
use App\Models\Security\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Group extends Model
{
use SoftDeletes;
public $table = 'group';
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
protected $dates = ['deleted_at'];
public $fillable = [
'name',
];
public static $rules = [
];
public function users()
{
return $this->hasMany(User::class);
}
public function resources()
{
return $this->belongsToMany(Resource::class, 'group_policy', 'group_id', 'resource_id')
->whereNull('group_policy.deleted_at')
->withPivot('allow')
->withTimestamps();
}
}
Resource Model proyect/app/Models/Security/Resource.php
<?php
namespace App\Models\Security;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Resource extends Model
{
use SoftDeletes;
public $table = 'resource';
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
protected $dates = ['deleted_at'];
public $fillable = [
'alias',
'uuid',
'type',
];
public static $rules = [
];
public static function isUUID($value)
{
$UUIDv4 = '/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i';
return preg_match($UUIDv4, $value);
}
public static function byAlias($value)
{
return Resource::where('alias', $value)->first();
}
}
There are a lot of things that I have not put here, but this is what I have so far
The problem i find with trying to combine permissions from a db with policies is when it comes to the ownership of a record.
Ultimately in our code we would like to check access to a resource using permission only. This is because as the list of roles grows we don't want to have to keep adding checks for these roles to the codebase.
If we have a users table we may want 'admin' (role) to be able to update all user records but a 'basic' user to only be able to update their own user record. We would like to be able to control this access SOLELY using the database.
However, if you have an 'update_user' permission then do you give it to both roles?
If you don't give it to the basic user role then the request won't get as far as the policy to check ownership.
Hence, you cannot revoke access for a basic user to update their record from the db alone.
Also the meaning of 'update_user' in the permissions table now implies the ability to update ANY user.
SOLUTION?
Add extra permissions to cater for the case where a user owns the record.
So you could have permissions to 'update_user' AND 'update_own_user'.
The 'admin' user would have the first permission whilst the 'basic' user would have the second one.
Then in the policy we check for the 'update_user' permission first and if it's not present we check for the 'update_own_user'.
If the 'update_own_user' permission is present then we check ownership. Otherwise we return false.
The solution will work but it seems ugly to have to have manage 'own' permissions in the db.
I am creating an web application using Laravel 5.2. I have login successfully into the application, but when i tried to logout. It does not allow me to do so.
When i investigate, i came to know that \Illuminate\Support\Facades\Auth::logout() returning null using dd(\Illuminate\Support\Facades\Auth::logout());. I have also tried $this-auth->logout(); this statement also return null.
I am not using default laravel scaffolding, instead i have create my usercontroller and doing the same thing.
Effort:
Route.php
Route::get('/', 'HomeController#index');
Route::get('logout/','UserController#logout');
Route::group(['middleware' => ['web']], function () {
Route::get('login/','UserController#loginForm');
Route::post('login/','UserController#login');
Route::get('register/','UserController#register');
Route::post('register/','UserController#store');
Route::get('home/',['as' => 'home', 'uses' => 'HomeController#index']);
});
UserController.php
namespace App\Http\Controllers;
use App\User;
use App\Profile;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* User model instance
* #var User
*/
protected $user;
protected $profile;
/**
* For Guard
*
* #var Authenticator
*/
protected $auth;
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct(Guard $auth, User $user)
{
$this->user = $user;
$this->auth = $auth;
$this->middleware('guest', ['except' => 'logout']);
}
public function login(Request $request)
{
if ($this->auth->attempt($request->only('email', 'password'))) {
// dd(\Illuminate\Support\Facades\Auth::user());
dd(\Illuminate\Support\Facades\Auth::user());
return redirect()->route('home');
}
return redirect('login')->withErrors([
'email' => 'The email or the password is invalid. Please try again.',
]);
}
/**
* Log the user out of the application.
*
* #return Response
*/
protected function logout()
{
// \Illuminate\Support\Facades\Auth::logout();
dd(\Illuminate\Support\Facades\Auth::logout());
$this->auth->logout();
\Session::flush();
return redirect('login');
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function loginForm()
{
return view('user.login', ['title' => 'Login Page']);
}
....
}
I am lot able to understand why user is not getting logout ? Please help Me.
I followed the laracasts tutorial on Socialite. My ultimate aim is to connect to azure ad, but I was having problems with various aspects of that so I thought I'd start with his github tutorial and get it working in principle first. I was fine until I tried to use middleware - now I get caught in infinite redirect loops. If I break out of the loop and go to the homepage, it has successfully logged me in - but obviously the user won't know that and will think it's failed.
Any help would be greatly appreciated.
Ed.
AuthController:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\AuthenticateUser;
class AuthController extends Controller {
public function login(AuthenticateUser $authenticateUser, Request $request) {
$authenticateUser->execute($request->has('code'), $this);
return \Socialite::with('github')->redirect();
}
public function logout() {
if (\Auth::check()) \Auth::logout();
return view('auth.loggedout');
}
}
AuthenticateUser:
<?php
namespace App;
use Illuminate\Contracts\Auth\Guard;
use Laravel\Socialite\Contracts\Factory as Socialite;
use App\Repositories\UserRepository;
use Request;
class AuthenticateUser {
private $socialite;
private $auth;
public function __construct(UserRepository $users, Socialite $socialite, Guard $auth) {
$this->users = $users;
$this->socialite = $socialite;
$this->auth = $auth;
}
public function execute($hasCode) {
if (!$hasCode) {
return $this->getAuthorizationFirst();
}
$user = $this->users->findbyEmail($this->getUser());
$this->auth->login($user, true);
return redirect('/');
}
public function getAuthorizationFirst() {
return $this->socialite->driver('github')->redirect();
}
public
function getUser() {
return $user = $this->socialite->driver('github')->user();
}
}
routes.php:
Route::get('o365/connect', 'AuthController#login');
Route::get('o365/callback', 'AuthController#login');
Route::get('auth/logout', 'AuthController#logout');
Authenticate Middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class Authenticate {
/**
* The Guard implementation.
*
* #var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* #param Guard $auth
* #return void
*/
public function __construct(Guard $auth) {
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next) {
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('o365/connect');
}
}
if (\Auth::check()) {
return $next($request);
}
}
}