I am getting error while making custom authentication for my laravel 5.2 however this code works fine on my laravel 5.1 My config/auth.php file
'providers' => [
'users' => [
'driver' => 'custom',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
My CustomUserProvider.php (Auth/CustomUserProvider) file
<?php namespace App\Auth;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
class CustomUserProvider implements UserProvider {
protected $model;
public function __construct(UserContract $model)
{
$this->model = $model;
}
public function retrieveById($identifier)
{
}
public function retrieveByToken($identifier, $token)
{
}
public function updateRememberToken(UserContract $user, $token)
{
}
public function retrieveByCredentials(array $credentials)
{
}
public function validateCredentials(UserContract $user, array $credentials)
{
}
}
My CustomAuthProvider.php file
<?php namespace App\Providers;
use App\User;
use Auth;
use App\Auth\CustomUserProvider;
use Illuminate\Support\ServiceProvider;
class CustomAuthProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
$this->app['auth']->extend('custom',function()
{
return new CustomUserProvider();
});
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
}
Now this works fine in laravel 5.1 in 5.2 i am getting error like
InvalidArgumentException in CreatesUserProviders.php line 40:
Authentication user provider [custom] is not defined.
The only point is to use
$this->app['auth']->provider(...
instead of
$this->app['auth']->extend(...
The last one is used in 5.1, the first one should be used in 5.2.
app/Models/User.php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable {
protected $connection='conn';
protected $table='users-custom';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'login', 'passwd'
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'passwd',
];
public function getAuthPassword(){
//your passwor field name
return $this->passwd;
}
public $timestamps = false;
}
create app/Auth/CustomUserProvider.php
namespace App\Auth;
use Illuminate\Support\Str;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Illuminate\Contracts\Auth\UserProvider;
/**
* Description of CustomUserProvider
*
*/
class CustomUserProvider implements UserProvider {
/**
* The hasher implementation.
*
* #var \Illuminate\Contracts\Hashing\Hasher
*/
protected $hasher;
/**
* The Eloquent user model.
*
* #var string
*/
protected $model;
/**
* Create a new database user provider.
*
* #param \Illuminate\Contracts\Hashing\Hasher $hasher
* #param string $model class name of model
* #return void
*/
public function __construct($model) {
$this->model = $model;
}
/**
* Retrieve a user by their unique identifier.
*
* #param mixed $identifier
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier) {
return $this->createModel()->newQuery()->find($identifier);
}
/**
* Retrieve a user by their unique identifier and "remember me" token.
*
* #param mixed $identifier
* #param string $token
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token) {
$model = $this->createModel();
return $model->newQuery()
->where($model->getAuthIdentifierName(), $identifier)
->where($model->getRememberTokenName(), $token)
->first();
}
/**
* Update the "remember me" token for the given user in storage.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param string $token
* #return void
*/
public function updateRememberToken(UserContract $user, $token) {
$user->setRememberToken($token);
$user->save();
}
/**
* Retrieve a user by the given credentials.
*
* #param array $credentials
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials) {
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// Eloquent User "model" that will be utilized by the Guard instances.
$query = $this->createModel()->newQuery();
foreach ($credentials as $key => $value) {
if (!Str::contains($key, 'password')) {
$query->where($key, $value);
}
}
return $query->first();
}
/**
* Validate a user against the given credentials.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param array $credentials
* #return bool
*/
public function validateCredentials(UserContract $user, array $credentials) {
//your method auth
$plain = $credentials['password'];
return md5($plain)==md5($user->getAuthPassword());
}
/**
* Create a new instance of the model.
*
* #return \Illuminate\Database\Eloquent\Model
*/
public function createModel() {
$class = '\\' . ltrim($this->model, '\\');
return new $class;
}
/**
* Gets the hasher implementation.
*
* #return \Illuminate\Contracts\Hashing\Hasher
*/
public function getHasher() {
return $this->hasher;
}
/**
* Sets the hasher implementation.
*
* #param \Illuminate\Contracts\Hashing\Hasher $hasher
* #return $this
*/
public function setHasher(HasherContract $hasher) {
$this->hasher = $hasher;
return $this;
}
/**
* Gets the name of the Eloquent user model.
*
* #return string
*/
public function getModel() {
return $this->model;
}
/**
* Sets the name of the Eloquent user model.
*
* #param string $model
* #return $this
*/
public function setModel($model) {
$this->model = $model;
return $this;
}
}
in config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users_office',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'users_office' => [
'driver' => 'customUser',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
in \vendor\laravel\framework\src\Illuminate\AuthCreatesUserProviders.php
public function createUserProvider($provider)
{
$config = $this->app['config']['auth.providers.'.$provider];
if (isset($this->customProviderCreators[$config['driver']])) {
return call_user_func(
$this->customProviderCreators[$config['driver']], $this->app, $config
);
}
switch ($config['driver']) {
case 'database':
return $this->createDatabaseProvider($config);
case 'eloquent':
return $this->createEloquentProvider($config);
case 'customUser':
return $this->createCustomUserProvider($config);
default:
throw new InvalidArgumentException("Authentication user provider [{$config['driver']}] is not defined.");
}
}
protected function createCustomUserProvider($config){
return new \App\Auth\CustomUserProvider($config['model']);
}
add App\Providers\CustomUserAuthProvider.php
namespace App\Providers;
use Auth;
use App\Models\User;
use App\Auth\CustomUserProvider;
use Illuminate\Support\ServiceProvider;
/**
* Description of CustomAuthProvider
*
*/
class CustomUserAuthProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
Auth::extend('customUser', function($app) {
// Return an instance of Illuminate\Contracts\Auth\UserProvider...
return new CustomUserProvider(new User);
});
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
}
Try by replacing the boot function as below:
public function boot()
{
Auth::provider('custom', function($app, array $config) {
// Return an instance of Illuminate\Contracts\Auth\UserProvider...
return new CustomUserProvider($app['custom.connection']);
});
}
Replace the boot function as below:
public function boot()
{
Auth::provider('customUser', function($app, array $config) {
return new CustomUserProvider($config['model']);
});
}
Related
In my LoginController I have:
protected $redirectTo = '';
I then do this:
public function boot()
{
Parent::boot();
$this->redirectTo = route('org.home');
$this->logoutTo = route('user.login');
}
But in a method in the controller I check and I get a BLANK value from $this->redirectTo
protected function authenticated(Request $request, $user)
{
dd($this->redirectTo);
}
How do I make the value of this variable dynamic and use the route name to assign its value?
Here is my whole controller based on the comments below:
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Which Authentication Guard we are working with
*
* #var string
*/
protected $guard = 'user';
/**
* URI where we redirect to after registration
*
* #var string
*/
protected $redirectTo = '';
/**
* URI where we redirect to after logout
*
* #var string
*/
protected $logoutTo = '';
/**
* LoginController constructor.
*/
public function __construct()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Parent::boot();
$this->redirectTo = route('org.home');
$this->logoutTo = route('user.login');
}
/**
* Show the application's login form.
*
* #return \Illuminate\Http\Response
*/
public function showLoginForm()
{
return view('auth.user.main.login');
}
/**
* Log the user out of the application.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function logout(Request $request)
{
Auth::guard($this->guard)->logout();
$request->session()->flush();
$request->session()->regenerate();
if ($request->ajax()) {
return response()->json([
'type' => 'success',
'message' => trans('auth.logout_ok')
]);
} else {
return redirect($this->logoutTo ?: '/');
}
}
/**
* The user has been authenticated.
*
* #param \Illuminate\Http\Request $request
* #param mixed $user
* #return mixed
*/
protected function authenticated(Request $request, $user)
{
// If this user belongs to a partner
if ($user->isPartner()) {
// And the partner is active, then continue
if (!$user->partner->isActive()) {
// Else respond with an error
$error = [
'type' => 'error',
'message' => trans('messages.partner_inactive')
];
if ($request->ajax()) {
return response()->json($error);
} else {
return redirect()->back()->withErrors($error);
}
}
}
dd($this->redirectTo);
// Set up the user's session
$this->setupSession();
if ($request->ajax()) {
return response()->json([
'type' => 'success',
'user' => auth()->check(),
'intended' => $this->redirectPath(),
'message' => trans('auth.logout_ok')
]);
} else {
return redirect()->intended($this->redirectPath());
}
}
/**
* Send the response after the user was authenticated.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
if ($this->authenticated($request, $this->guard()->user())) {
return true;
} else {
if ($request->ajax()) {
return response()->json([
'type' => 'error',
'user' => auth()->check(),
'intended' => $this->redirectPath(),
'message' => trans('auth.not_login')
]);
} else {
return redirect()->intended($this->redirectPath());
}
}
}
/**
* Get the failed login response instance.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse
*/
protected function sendFailedLoginResponse(Request $request)
{
$errors = [$this->username() => trans('auth.failed')];
if ($request->expectsJson()) {
return response()->json($errors, 422);
}
return redirect()->back()
->withInput($request->only($this->username(), 'remember'))
->withErrors($errors);
}
/**
* Set up all session variables here
*/
private function setupSession()
{
// session()->put('user', Auth::user());
}
}
I had to put my assignments here
public function __construct()
{
$this->redirectTo = route('org.home');
$this->logoutTo = route('user.login');
}
Hi I'm developing user authentication on basis of SOAP API response using Laravel 5.4, for that I've implemented UserProvider and AuthServiceProvider but still unsuccessful.
Here is the implementation of UserProvider
namespace App\Authentication;
use App\Http\Controllers\ApiCallsController;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider as IlluminateUserProvider;
use Config;
use Illuminate\Foundation\Auth\User;
class UserProvider implements IlluminateUserProvider
{
/**
* #param mixed $identifier
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
// Get and return a user by their unique identifier
$http_client = new ApiCallsController();
$check_user = $http_client->HttpClient("GET", Config::get('constants.c2mCloud') . '/user/UserTypeOrName/' . $identifier);
$users = json_decode($check_user);
if ($users->responseCode == "00") {
if (count($users->users) > 0) {
$user = new User();
$users = $users->users[0];
$user->id = $users->userId;
$user->c2MUsername = $users->c2MUsername;
$user->createdAt = $users->createdAt;
$user->lastModifiedAt = $users->lastModifiedAt;
$user->password = $users->password;
$user->userType = $users->userType;
$user->active = $users->active;
return new \App\User([
'id' => $users->userId
]);
}
}
}
/**
* #param mixed $identifier
* #param string $token
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
// Get and return a user by their unique identifier and "remember me" token
}
/**
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param string $token
* #return void
*/
public function updateRememberToken(Authenticatable $user, $token)
{
// Save the given "remember me" token for the given user
}
/**
* Retrieve a user by the given credentials.
*
* #param array $credentials
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
// Get and return a user by looking up the given credentials
$http_client = new ApiCallsController();
$check_user = $http_client->HttpClient("GET", Config::get('constants.c2mCloud') . '/user/UserTypeOrName/' . $credentials['c2MUsername']);
$users = json_decode($check_user);
if ($users->responseCode == "00") {
if (count($users->users) > 0) {
$users = $users->users[0];
// return $users->users[0];
return new \App\User([
'id' => $users->userId,
// 'c2MUsername' => $users->c2MUsername,
// 'createdAt' => $users->createdAt,
// ''
]);
}
}
}
/**
* Validate a user against the given credentials.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param array $credentials
* #return bool
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
// Check that given credentials belong to the given user
}
}
And implementation of AuthServiceProvider
<?php
namespace App\Authentication;
use Auth;
use App\Authentication\UserProvider;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* #return void
*/
public function boot()
{
Auth::provider('c2m_provider', function($app, array $config) {
return new UserProvider();
});
}
/**
* Register bindings in the container.
*
* #return void
*/
public function register()
{
//
}
}
and my User class is
<?php
namespace App;
use Illuminate\Contracts\Auth\Authenticatable;
class User implements Authenticatable
{
/**
* #return string
*/
public function getAuthIdentifierName()
{
// Return the name of unique identifier for the user (e.g. "id")
}
/**
* #return mixed
*/
public function getAuthIdentifier()
{
// Return the unique identifier for the user (e.g. their ID, 123)
}
/**
* #return string
*/
public function getAuthPassword()
{
// Returns the (hashed) password for the user
}
/**
* #return string
*/
public function getRememberToken()
{
// Return the token used for the "remember me" functionality
}
/**
* #param string $value
* #return void
*/
public function setRememberToken($value)
{
// Store a new token user for the "remember me" functionality
}
/**
* #return string
*/
public function getRememberTokenName()
{
// Return the name of the column / attribute used to store the "remember me" token
}
}
And in my controller after using Auth::login($user); when I check is user logged in by Auth::check() it alwys return false.
Anyone who can help me?
Try using Auth::attempt($username,$password)
if (Auth::attempt($username,$password)) {
//user is logged in
} else {
//user is not logged in
}
Auth::check() simply checks if the user is logged in. It doesn't actually process the login.
For custom Authentication, we need in to implement these 4 classes in laravel 5.4. And this implementation is working for me in a live project.
namespace App\Auth;
use Illuminate\Contracts\Auth\Authenticatable as User_Authenticatable;
class Authenticatable implements User_Authenticatable
{
/**
* The column name of the "remember me" token.
*
* #var string
*/
protected $rememberTokenName = 'remember_token';
/**
* Get the name of the unique identifier for the user.
*
* #return string
*/
public function getAuthIdentifierName()
{
return "id";
}
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->{$this->getAuthIdentifierName()};
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the token value for the "remember me" session.
*
* #return string
*/
public function getRememberToken()
{
if (! empty($this->getRememberTokenName())) {
return $this->{$this->getRememberTokenName()};
}
}
/**
* Set the token value for the "remember me" session.
*
* #param string $value
* #return void
*/
public function setRememberToken($value)
{
if (! empty($this->getRememberTokenName())) {
$this->{$this->getRememberTokenName()} = $value;
}
}
/**
* Get the column name for the "remember me" token.
*
* #return string
*/
public function getRememberTokenName()
{
return $this->rememberTokenName;
}
}
2nd
namespace App\Auth;
use Illuminate\Contracts\Auth\Access\Authorizable as User_Authorizable;
use Illuminate\Contracts\Auth\Access\Gate;
Class Authorizable Implements User_Authorizable
{
/**
* Determine if the entity has a given ability.
*
* #param string $ability
* #param array|mixed $arguments
* #return bool
*/
public function can($ability, $arguments = [])
{
return app(Gate::class)->forUser($this)->check($ability, $arguments);
}
/**
* Determine if the entity does not have a given ability.
*
* #param string $ability
* #param array|mixed $arguments
* #return bool
*/
public function cant($ability, $arguments = [])
{
return ! $this->can($ability, $arguments);
}
/**
* Determine if the entity does not have a given ability.
*
* #param string $ability
* #param array|mixed $arguments
* #return bool
*/
public function cannot($ability, $arguments = [])
{
return $this->cant($ability, $arguments);
}
}
3rd
namespace App\Auth;
use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification;
class CanResetPassword extends ResetPasswordNotification
{
}
4th
<?php
namespace App\Auth;
use App\Http\Controllers\ApiCallsController;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider as IlluminateUserProvider;
use Config;
use App\Models\ApiUser;
class UserProvider implements IlluminateUserProvider
{
/**
* #param mixed $identifier
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
// Get and return a user by their unique identifier
return ApiUser::getUser(null, null, $identifier);
}
/**
* #param mixed $identifier
* #param string $token
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
// Get and return a user by their unique identifier and "remember me" token
}
/**
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param string $token
* #return void
*/
public function updateRememberToken(Authenticatable $user, $token)
{
// Save the given "remember me" token for the given user
}
/**
* Retrieve a user by the given credentials.
*
* #param array $credentials
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
// Get and return a user by looking up the given credentials
return ApiUser::getUser($credentials['c2MUsername']);
}
/**
* Validate a user against the given credentials.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param array $credentials
* #return bool
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
// Check that given credentials belong to the given user
$api_user = \App\Models\ApiUser::getUser($credentials['c2MUsername']);
if(!empty($api_user)){
return true;
}
return false;
}
}
My Custom Auth Provider
<?php
/**
* Created by PhpStorm.
* User: CresenTech
* Date: 23-Oct-17
* Time: 7:19 PM
*/
namespace App\Providers;
use Illuminate\Support\Facades\Auth;
use App\Auth\UserProvider;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class CustomAuthProvider extends ServiceProvider {
/**
* The policy mappings for the application.
*
* #var array
*/
// protected $policies = [
//// 'App\Model' => 'App\Policies\ModelPolicy',
// ];
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
/**
* Register any authentication / authorization services.
*
* #return void
*/
// $this->registerPolicies();
Auth::provider('custom',function()
{
return new UserProvider();
});
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
}
And my auth.php in config directory
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
//
// 'c2m' => [
// 'driver' => 'session',
// 'provider' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
// 'users' => [
// 'driver' => 'eloquent',
// 'model' => App\User::class,
// ],
'users' => [
'driver' => 'custom',
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
// 'table' => 'password_resets',
'expire' => 60,
],
],
];
I am using laravel-echo-server to run Laravel Echo to broadcast events.
I have a user counter channel which shows all the users on the app. For this I am using a presence channel. This works fine for logged in users, but guests just never get connected.
I've setup the below in the BroadcastServiceProvider:
Broadcast::channel('global', function () {
return ['name' => 'guest'];
});
Which from what I can tell, should allow everyone in as 'guests'. I'm guessing there's some middleware or auth that's being checked before this that I need to disable for this channel.
Any help on getting all clients joining this presence channel would be much appreciated!
The other solutions didn't work for me for a guest presence channel, this is what I ended up with:
// routes/channels.php
<?php
use Illuminate\Auth\GenericUser;
/*
|--------------------------------------------------------------------------
| Broadcast Channels
|--------------------------------------------------------------------------
|
| Here you may register all of the event broadcasting channels that your
| application supports. The given channel authorization callbacks are
| used to check if an authenticated user can listen to the channel.
|
*/
Route::post('/custom/broadcast/auth/route', function () {
$user = new GenericUser(['id' => microtime()]);
request()->setUserResolver(function () use ($user) {
return $user;
});
return Broadcast::auth(request());
});
Broadcast::channel('online.{uuid}', function ($user, $uuid) {
return [
'id' => $user->id,
'uuid' => $uuid
];
});
You may create a temporary user with factory(User::class)->make(...) and authenticate it with a middleware to use it as a guest.
Step 1: Creating the middleware
Run: php artisan make:middleware AuthenticateGuest
In app/Http/Middleware/AuthenticateGuest.php:
public function handle($request, Closure $next)
{
Auth::login(factory(User::class)->make([
'id' => (int) str_replace('.', '', microtime(true))
]));
return $next($request);
}
Now setup the AuthenticateGuest middleware in Kernel.php.
In app\Http\Kernel.php:
protected $routeMiddleware = [
...
'authenticate-guest' => \App\Http\Middleware\AuthenticateGuest::class,
];
Step 2: Setup Broadcast::channel route
In routes/channels.php:
Broadcast::channel('chatroom', function ($user) {
return $user; // here will return the guest user object
});
More at: https://laravel.com/docs/8.x/broadcasting#authorizing-presence-channels
For anyone looking for answers to this. It is indeed possible to auth guests into presence channels you just need to override the Broadcast::routes() from the service provider with your own.
As an example my presence channel 'global' accepts guests:
Route::post('/broadcasting/auth', function(Illuminate\Http\Request $req) {
if($req->channel_name == 'presence-global'){return 'global';}
return abort(403);
});
This could be extended in various directions, or could continue to pass other presence and private channels through to the default Broadcast::auth method
You can create your own auth guard and it's also pretty simple but more complex.
Create a class which will implement Authenticable Interface.
Create UserProvider.
Create a new Guard.
Register Guard and UserProvider in AuthServiceProvider.
Add provider and guard in config/auth.php
Use your new guard.
Advantages
You don't have to modify auth endpoint
You don't have to change default guard
You base on Laravel Auth system
Keep support of multiple tabs in the browser
Can be used with web guard at the same time
Keep all the advantages of using PresenceChannel
Disadvantages
A lot to code
So,
1. Create a new class which will implement Authenticable interface.
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use JsonSerializable;
/**
* #property string $id
* #property string $name
*/
class Session implements Authenticatable, Jsonable, Arrayable, JsonSerializable
{
private $id;
private $attributes = [];
public function __construct($id)
{
$this->id = $id;
$this->name = "Guest";
}
/**
* Get the name of the unique identifier for the user.
*
* #return string
*/
public function getAuthIdentifierName()
{
return 'id';
}
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->{$this->getAuthIdentifierName()};
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return "";
}
/**
* Get the token value for the "remember me" session.
*
* #return string
*/
public function getRememberToken()
{
return $this->{$this->getAuthIdentifierName()};
}
/**
* Set the token value for the "remember me" session.
*
* #param string $value
* #return void
*/
public function setRememberToken($value)
{
$this->{$this->getRememberToken()} = $value;
}
/**
* Get the column name for the "remember me" token.
*
* #return string
*/
public function getRememberTokenName()
{
return "token";
}
public function __get($name)
{
return $this->attributes[$name];
}
public function __set($name, $value)
{
$this->attributes[$name] = $value;
}
/**
* Convert the object to its JSON representation.
*
* #param int $options
* #return string
*/
public function toJson($options = 0)
{
return json_encode($this);
}
/**
* Get the instance as an array.
*
* #return array
*/
public function toArray()
{
return $this->attributes;
}
/**
* Specify data which should be serialized to JSON
* #link https://php.net/manual/en/jsonserializable.jsonserialize.php
* #return mixed data which can be serialized by <b>json_encode</b>,
* which is a value of any type other than a resource.
* #since 5.4.0
*/
public function jsonSerialize()
{
return $this->attributes;
}
}
Modify this as you wish, but you shouldn't serialize $id property
2. Create UserProvider
<?php namespace App\Extensions;
use App\Models\Session;
use Illuminate\Cache\Repository;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Support\Fluent;
use Illuminate\Support\Str;
class SessionUserProvider implements UserProvider
{
private $store;
/**
* SessionUserProvider constructor.
* #param Repository $store
*/
public function __construct(Repository $store)
{
$this->store = $store;
}
/**
* Retrieve a user by their unique identifier.
*
* #param mixed $identifier
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
return new Session(
$this->getUniqueTokenForSession($identifier)
);
}
/**
* Retrieve a user by their unique identifier and "remember me" token.
*
* #param mixed $identifier
* #param string $token
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
return null;
}
/**
* Update the "remember me" token for the given user in storage.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param string $token
* #return void
*/
public function updateRememberToken(Authenticatable $user, $token)
{
return;
}
/**
* Retrieve a user by the given credentials.
*
* #param array $credentials
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
return null;
}
private function unpack($data)
{
return json_decode($data);
}
private function getUniqueTokenForSession($id)
{
return $this->retrieveCacheDataForSession($id)
->get('uuid');
}
private function retrieveCacheDataForSession($id)
{
$fluent = new Fluent(
$this->unpack(
$this->store->has($id) ? $this->store->get($id) : "[]"
)
);
if(!$fluent->__isset('uuid')) {
$fluent->__set('uuid', Str::random(128));
}
$this->store->put($id, $fluent->toJson(), 60 * 60 * 60);
return $fluent;
}
/**
* Validate a user against the given credentials.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param array $credentials
* #return bool
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
return null;
}
}
Identifier property in retrieveById method is always session id if you are using broadcasting so you can also use this as a token.
3. Create new Guard
<?php namespace App\Services\Auth;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Http\Request;
class GuestGuard implements Guard
{
private $user;
protected $request;
protected $provider;
/**
* GuestGuard constructor.
* #param UserProvider $provider
* #param Request $request
*/
public function __construct(UserProvider $provider, Request $request)
{
$this->provider = $provider;
$this->request = $request;
}
/**
* Determine if the current user is authenticated.
*
* #return bool
*/
public function check()
{
return !is_null($this->user);
}
/**
* Determine if the current user is a guest.
*
* #return bool
*/
public function guest()
{
return !$this->check();
}
/**
* Get the currently authenticated user.
*
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
if($this->check()) {
return $this->user;
}
$this->setUser(
$this->provider->retrieveById(
$this->request->session()->getId()
)
);
return $this->user;
}
/**
* Get the ID for the currently authenticated user.
*
* #return int|null
*/
public function id()
{
return !is_null($this->user) ? $this->user->id : null;
}
/**
* Validate a user's credentials.
*
* #param array $credentials
* #return bool
*/
public function validate(array $credentials = [])
{
return false;
}
/**
* Set the current user.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #return void
*/
public function setUser(Authenticatable $user)
{
$this->user = $user;
}
}
Here in user method you pass session id as identifier, using broadcasting only this method is nessesary.
4. Register Guard and UserProvider in AuthServiceProvider.
// app/Providers/AuthServiceProvider.php
/**
* Register any authentication / authorization services.
*
* #return void
*/
public function boot()
{
$this->registerPolicies();
Auth::provider('sessions', function (Application $app) {
return new SessionUserProvider(
$app->make('cache.store')
);
});
Auth::extend('guest', function (Application $app, $name, array $config) {
return new GuestGuard(Auth::createUserProvider($config['provider']), $app->make('request'));
});
}
5.1 Add provider in config/auth.php
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// New
'sessions' => [
'driver' => 'sessions',
'model' => App\Models\Session::class,
],
],
5.2 Add guard in config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
// New
'guest' => [
'driver' => 'guest',
'provider' => 'sessions'
]
],
6. Use your new guard
// routes/channels.php
Broadcast::channel('chat.{id}', function (Authenticatable $user){
return $user;
}, ['guards' => ['guest']]);
Notice that you can use 'web' as a guard at the same time ('web' should be before 'guest'). It allows you to find out who is a guest and who is a logged in user - you can just check instance of Authenticable in channel callback.
And that how it looks in the laravel-echo-server database
With the help of Renan Coelho i got it to work. The missing part for me was to override the Broadcast::routes() method with the following:
Route::post('/broadcasting/auth', function (Illuminate\Http\Request $req) {
return Broadcast::auth($req);
});
Route::post('/broadcasting/auth'... is actually a route that gets added through the "Broadcast::routes()" method. This is why we override it here. You can see the active routes by typing php artisan route:list in your terminal.
Then, Renan Coelho already said, i had to add a custom Middleware (AuthenticateGuest) that creates a random user for me. (This is the hacky part) and add it to the $middleware array in the kernel.php:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
\Barryvdh\Cors\HandleCors::class,
\App\Http\Middleware\AuthenticateGuest::class
];
The AuthenticateGuest Middleware looks like the following:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use App\User;
class AuthenticateGuest
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
Auth::login(factory(User::class)->make([
'id' => (int)str_replace('.', '', microtime(true))
]));
return $next($request);
}
}
Hope that helps someone,
Sebastian
My solution to issue:
BroadcastServiceProvider.php (~/app/Providers/)
public function boot()
{
if (request()->hasHeader('V-Auth')) { /* Virtual client. */
Broadcast::routes(['middleware' => 'client_chat.broadcast.auth']);
} else {
Broadcast::routes();
}
require base_path('routes/channels.php');
}
Kernel.php (~/app/Http/)
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
...
'client_chat.broadcast.auth' => \App\Http\Middleware\ClientChatBroadcasting::class,
];
ClientChatBroadcasting.php (~/app/Http/Middleware/)
public function handle($request, Closure $next)
{
if (/** your condition **/) {
$fakeUser = new User;
$fakeUser->virtual_client = true;
$fakeUser->id = /** whatever you want **/;
$fakeUser->name = '[virtual_client]';
$fakeUser->asdasdasdasdasd = 'asdasdasdasdasd';
$request->merge(['user' => $fakeUser]);
$request->setUserResolver(function () use ($fakeUser) {
return $fakeUser;
});
}
return $next($request);
}
ChatChannel.php (~/app/Broadcasting/Chat/)
Broadcast::channel('chat.{chatId}', ChatChannel::class); Channel Classes
public function join($member/**($fakeUser)**/, $chatId)
{
$memberData = [/** your data **/];
/* If there is no member data (null), then there will be an authentication error. */
return $memberData;
}
[place in your js file, where you want connect to broadcasting]
this.Echo = new Echo({
broadcaster: 'socket.io',
host: /** your host **/,
reconnectionAttempts: 60,
encrypted: true,
auth: {
headers: {
'V-Auth': true,
'Access-Token': accessToken,
'Virtual-Id': virtualId,
'Chat-Id': chatId
}
}
});
I made it here reading this blog, getting the /broadcasting/auth error. The answers were very helpful but I didn't find the complete answer I needed.
I did this in Laravel 9.x so FYI it will work in that version too.
The major missing piece of code I needed was in the routes/web.php:
use Illuminate\Support\Facades\Route;
Broadcast::routes([
'middleware' => ['web', 'authenticate-guest'],
]);
Route::get('/', function () {
return view('welcome');
});
However I will add the rest down here in case anyone needs the whole thing:
Remove comment in app.config provider:
App\Providers\BroadcastServiceProvider::class,
Make middleware: php artisan make:middleware AuthenticateGuest.php
Then update it, in app/Http/Middleware
public function handle(Request $request, Closure $next)
{
Auth::login(User::factory()->make([
'id' => (int) str_replace('.', '', microtime(true))
]));
return $next($request);
}
app/Http/Kernel.php File..
protected $routeMiddleware = [
...
'authenticate-guest' => \App\Http\Middleware\AuthenticateGuest::class
];
app/Providers/BroadcastServiceProvider.php file should be this, but check:
public function boot()
{
Broadcast::routes();
require base_path('routes/channels.php');
}
Lastly, the routes/channel.php file:
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('common_room', function ($user) {
return true;
});
To finish everything off, do a npm run dev, followed by php artisan route:clear and maybe php artisan cache:clear/php artisan config:clear as well. Hope that helps!
I am trying to integrate the auth in laravel 5.4 within an existing database where the user and password fields have other names (memberid, passwordnew_enc). With the bellow changes and forcing the create function in RegisterController to use MD5 I managed to make the registration work. It also logins fine after registration. However the actual login form returns:
These credentials do not match our records.
So far I have changed the User.php
public function getAuthPassword()
{
return $this->passwordnew_enc;
}
and
public function setPasswordAttribute($value)
{
$this->attributes['password'] = md5($value);
}
Also on LoginController.php
public function username()
{
return 'memberid';
}
Did I miss something ?
I only need to change the two column names to fit and the password encryption from bcrypt to md5
I would make custom user provider php artisan make:provider CustomUserProvider:
<?php
namespace App\Providers;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
class CustomUserProvider extends EloquentUserProvider {
/**
* Validate a user against the given credentials.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param array $credentials
* #return bool
*/
public function validateCredentials(UserContract $user, array $credentials)
{
$plain = $credentials['password']; // will depend on the name of the input on the login form
$hashedValue = $user->getAuthPassword();
if ($this->hasher->needsRehash($hashedValue) && $hashedValue === md5($plain)) {
$user->passwordnew_enc = bcrypt($plain);
$user->save();
}
return $this->hasher->check($plain, $user->getAuthPassword());
}
}
This way if the password exists using md5 it will allow it to work once and then rehash it.
You will register the CustomUserProvider in App\Providers\AuthServiceProvider boot() as follows:
$this->app['auth']->provider('custom', function ($app, array $config) {
$model = $app['config']['auth.providers.users.model'];
return new CustomUserProvider($app['hash'], $model);
});
Edit your config/auth.php
'providers' => [
'users' => [
'driver' => 'custom',
'model' => App\User::class,
],
],
You will also need to add the following as mentioned previously...
app\Http\Controllers\Auth\LoginController.php
public function username()
{
return 'memberid';
}
app\User.php
public function getAuthIdentifierName()
{
return 'memberid';
}
public function getAuthIdentifier()
{
return $this->memberid;
}
public function getAuthPassword()
{
return $this->passwordnew_enc;
}
Alright I got it
app\User.php
public function setPasswordAttribute($value)
{
$this->attributes['password'] = md5($value);
}
public function getAuthPassword()
{
return $this->passwordnew_enc;
}
public function getAuthIdentifierName()
{
return 'memberid';
}
app\Http\Controllers\Auth\LoginController.php
public function username()
{
return 'memb___id';
}
config\app.php
// Illuminate\Hashing\HashServiceProvider::class,
App\Providers\MD5HashServiceProvider::class,
app\Providers\MD5HashServiceProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class MD5HashServiceProvider 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 \MD5Hasher;
});
}
/**
* Get the services provided by the provider.
*
* #return array
*/
public function provides()
{
return ['hash'];
}
}
lib\MD5Hasher\MD5Hasher.php
<?php
class MD5Hasher implements Illuminate\Contracts\Hashing\Hasher
{
/**
* Hash the given value.
*
* #param string $value
* #return array $options
* #return string
*/
public function make($value, array $options = array())
{
return md5($value); //hash('md5', $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 = array())
{
return $this->make($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 = array())
{
return false;
}
}
composer.json
...
"autoload": {
"classmap": [
...
"app/Lib"
],
...
upful's code worked for me (in Laravel 5.4)
But I needed to add:
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
in the CustomUserProvider class.
I am new to couchbase and laravel. I am developing an entry form. I am using couchbase as database and in the back-end i am using laravel. when ever i try to insert data in the couchbase, although the query run, but it prints the data on the screen, rather than it stores in the database. Please help me in this issue
This is my model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Member extends Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Member extends Model
{
//
protected $table = '';
protected $primaryKey = 'id';
public $timestamps = false;
public static $couchbase_bucket = 'default';
public static $couchbase_doc = 'doc1';
protected $fillable = [
'id',
'name',
'father_name',
'constituency' ,
'seat_type',
'profession' ,
'deprtment' ,
'cabinet_post',
'party',
'date_of_birth',
'religon' ,
'marital_status',
'gender' ,
'education',
'present_contact',
'permanent_contact'
];
public static function create(array $attributes = array()){
die(print_r($attributes));
$value = [
'id' => intval($attributes['id']),
'name' => $attributes['name'],
'father_name' => $attributes['father_name'],
'constituency' => $attributes['constituency'],
'seat_type' => $attributes['seat_type'],
'profession' => $attributes['profession'],
'deprtment' => $attributes['department'],
'cabinet_post' => $attributes['cabinet_post'],
'party' => $attributes['party'],
'date_of_birth' => $attributes['date_of_birth'],
'religon' => $attributes['religon'],
'marital_status' => $attributes['marital_status'],
'gender' => $attributes['gender'],
'education' => $attributes['education'],
'present_contact' => $attributes['present_contact'],
'permanent_contact' => $attributes['permanent_contact'],
];
$key = 'insert:and:delete';
$result = \DB::connection('couchbase')->table(self::$couchbase_bucket)->key($key)->upsert($value);
return $result;
}
public static function all($columns = array()){
return \DB::connection('couchbase')->table(self::$couchbase_bucket)->get();
// DB::connection('couchbase')
// ->table('testing')->where('whereKey', 'value')->get();
}
public static function one($id){
return \DB::connection('couchbase')->table(self::$couchbase_bucket)->where('id',$id)->get();
}
}
And the controller is
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Member;
class memberController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
//
$memberdata = Member::all();
return view('member.index')->withuserdata($userdata);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
//
return view('member.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
$input = $request->all();
Member::create($input);
//return redirect('member/index');
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}