Custom authentication through API - php

I have a laravel API project. I want to be able to send a login request and get back a token depending on some custom logic. I am not using a database so i cant use the default auth.
I have set up a provider called AuthCustomProvider.
namespace App\Providers;
use Auth;
use App\Authentication\UserProvider;
use Illuminate\Support\ServiceProvider;
class AuthCustomProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* #return void
*/
public function boot()
{
Auth::provider('custom_auth', function($app, array $config) {
return new UserProvider();
});
}
/**
* Register bindings in the container.
*
* #return void
*/
public function register()
{
//
}
}
I have then added this to the config/app.php file in the providers array:
'providers' => [
App\Providers\AuthCustomProvider::class,
Then i added my custom providers driver to the config/auth.php file in the providers array:
'providers' => [
'users' => [
'driver' => 'custom_auth',
],
],
As im not using a database, I took out the model property
Lastly I created a folder called App/Authentication which i put my UserProvider.php file in which is this:
<?php
namespace App\Authentication;
use Illuminate\Contracts\Auth\UserProvider as IlluminateUserProvider;
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
}
/**
* #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
}
/**
* 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
}
}
So lastly i make a function on the login controller. This is what the api call goes to:
public function Login(Request $request)
{
$user = Consultant::lookup('UserId', 1);
//Returns collection of user details (user id, username etc)
//Logic will go here in the future
$logThemIn = true;
if ($logThemIn)
{
auth()->login($user);
//return oauth2 token
}
}
So this is where im at now, if i run this, im getting the error:
'Declaration of App\Authentication\UserProvider::updateRememberToken(App\Authentication\Authenticatable $user, $token) must be compatible with Illuminate\Contracts\Auth\UserProvider::updateRememberToken(Illuminate\Contracts\Auth\Authenticatable $user, $token)'
Im new to laravel and there isnt alot of tutorials for what im trying to do that i can find. Any help is greatly appriciated

Change your UserProvider to this which uses Illuminate\Contracts\Auth\Authenticatable instead of App\Authentication\Authenticatable, php will load a class from the current namespace if one isn't specified.
<?php
namespace App\Authentication;
use Illuminate\Contracts\Auth\UserProvider as IlluminateUserProvider;
use Illuminate\Contracts\Auth\Authenticatable;
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
}
/**
* #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
}
/**
* 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
}
}

You forgot to import Authenticatable. Just add:
use Illuminate\Contracts\Auth\Authenticatable;

Related

Laravel - SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '1616818311712'

I am new to Laravel and I am using version 5.8.38. I am using its Authentication system in my project, but whenever I use the "Reset Password" option, after I enter the email address where the Reset Password email is going to be sent to. I get the following error:
SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '1616819329600' for column `proyectolaravel`.`password_resets`.`created_at` at row 1 (SQL: insert into `password_resets` (`email`, `token`, `created_at`) values (andre_jack#hotmail.com, $2y$10$kCwg25dPXcmsn4msea37FOD3ocpHHv1.q1A89dNfbMDADsOnNOole, 1616819329600))
I have been trying to fix this problem but I have not been able to find anything related to this error regarding password_resets for Laravel.
I do not know why the date value for "created_at" is being saved as "1616819329600", and I wonder if there is any way to solve this. For what I have researched, I think the problem relays in the file DatabaseTokenRepository at vendor\laravel\framework\src\Illuminate\Auth\Passwords\DatabaseTokenRepository.php but I know that I should not manipulate those files.
If it is of any use, I share with you the content of that file:
<?php
namespace Illuminate\Auth\Passwords;
use Illuminate\Support\Str;
use Illuminate\Support\Carbon;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class DatabaseTokenRepository implements TokenRepositoryInterface
{
/**
* The database connection instance.
*
* #var \Illuminate\Database\ConnectionInterface
*/
protected $connection;
/**
* The Hasher implementation.
*
* #var \Illuminate\Contracts\Hashing\Hasher
*/
protected $hasher;
/**
* The token database table.
*
* #var string
*/
protected $table;
/**
* The hashing key.
*
* #var string
*/
protected $hashKey;
/**
* The number of seconds a token should last.
*
* #var int
*/
protected $expires;
/**
* Create a new token repository instance.
*
* #param \Illuminate\Database\ConnectionInterface $connection
* #param \Illuminate\Contracts\Hashing\Hasher $hasher
* #param string $table
* #param string $hashKey
* #param int $expires
* #return void
*/
public function __construct(ConnectionInterface $connection, HasherContract $hasher,
$table, $hashKey, $expires = 60)
{
$this->table = $table;
$this->hasher = $hasher;
$this->hashKey = $hashKey;
$this->expires = $expires * 60;
$this->connection = $connection;
}
/**
* Create a new token record.
*
* #param \Illuminate\Contracts\Auth\CanResetPassword $user
* #return string
*/
public function create(CanResetPasswordContract $user)
{
$email = $user->getEmailForPasswordReset();
$this->deleteExisting($user);
// We will create a new, random token for the user so that we can e-mail them
// a safe link to the password reset form. Then we will insert a record in
// the database so that we can verify the token within the actual reset.
$token = $this->createNewToken();
$this->getTable()->insert($this->getPayload($email, $token));
return $token;
}
/**
* Delete all existing reset tokens from the database.
*
* #param \Illuminate\Contracts\Auth\CanResetPassword $user
* #return int
*/
protected function deleteExisting(CanResetPasswordContract $user)
{
return $this->getTable()->where('email', $user->getEmailForPasswordReset())->delete();
}
/**
* Build the record payload for the table.
*
* #param string $email
* #param string $token
* #return array
*/
protected function getPayload($email, $token)
{
return ['email' => $email, 'token' => $this->hasher->make($token), 'created_at' => new Carbon];
}
/**
* Determine if a token record exists and is valid.
*
* #param \Illuminate\Contracts\Auth\CanResetPassword $user
* #param string $token
* #return bool
*/
public function exists(CanResetPasswordContract $user, $token)
{
$record = (array) $this->getTable()->where(
'email', $user->getEmailForPasswordReset()
)->first();
return $record &&
! $this->tokenExpired($record['created_at']) &&
$this->hasher->check($token, $record['token']);
}
/**
* Determine if the token has expired.
*
* #param string $createdAt
* #return bool
*/
protected function tokenExpired($createdAt)
{
return Carbon::parse($createdAt)->addSeconds($this->expires)->isPast();
}
/**
* Delete a token record by user.
*
* #param \Illuminate\Contracts\Auth\CanResetPassword $user
* #return void
*/
public function delete(CanResetPasswordContract $user)
{
$this->deleteExisting($user);
}
/**
* Delete expired tokens.
*
* #return void
*/
public function deleteExpired()
{
$expiredAt = Carbon::now()->subSeconds($this->expires);
$this->getTable()->where('created_at', '<', $expiredAt)->delete();
}
/**
* Create a new token for the user.
*
* #return string
*/
public function createNewToken()
{
return hash_hmac('sha256', Str::random(40), $this->hashKey);
}
/**
* Get the database connection instance.
*
* #return \Illuminate\Database\ConnectionInterface
*/
public function getConnection()
{
return $this->connection;
}
/**
* Begin a new database query against the table.
*
* #return \Illuminate\Database\Query\Builder
*/
protected function getTable()
{
return $this->connection->table($this->table);
}
/**
* Get the hasher instance.
*
* #return \Illuminate\Contracts\Hashing\Hasher
*/
public function getHasher()
{
return $this->hasher;
}
}
Any help will be highly appreciated!
I FINALLY figured it out, the created_at field was trying to be saved with the value of 1616819329600 because there was a conflict between Laravel's original Password Service Provider, and Jenssegers' Password Service Provider (which was being used before I migrated my project from MongoDB to MySQL) at "config/app.php".
So, when my problem was ocurring, my app.php file looked like this:
(...)
/*
* Package Service Providers...
*/
Jenssegers\Mongodb\MongodbServiceProvider::class,
Jenssegers\Mongodb\Auth\PasswordResetServiceProvider::class,
(...)
And finally, after the fix, I just deleted those lines of code and my app.php now looks this way:
(...)
/*
* Package Service Providers...
*/
/*
* Application Service Providers...
*/
(...)
I guess you could say that the exact reason this happened is that you shouldn't use two package service providers ending with the same name at the same file, as you can see in the following example:
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Jenssegers\Mongodb\Auth\PasswordResetServiceProvider::class,
You have to use like this
use Carbon/Carbon;
Add above in header section
protected function getPayload($email, $token)
{
return ['email' => $email, 'token' => $this->hasher->make($token), 'created_at' => Carbon::now()->format('Y-m-d H:i:s')];
}

Laravel middleware limits access to unwanted functions

I am doing a project in Laravel.
I have a database with posts and users. These posts can be modified and edited by the user who created it and the admin.
To do this I created a new field for users, there is an admin and two editor.
After limiting the access with the middleware, only the admin and editor can access the posts.
$this->middleware('auth',['only' => ['create', 'store', 'edit', 'update', 'destroy']]);
$this->middleware(['auth', 'roles:admin'],['only' => ['edit', 'update', 'destroy']]);
The problem is that now only the admin can access the edit and delete post functions. Publishers are redirected to the home page.
Is there a way to put an if that bypasses the middleware redirect or something similar?
I'd use a policy to simplify things, and remove the middleware.
Create Policy
php artisan make:policy PostPolicy --model=Post
Resulting in this file
<?php
namespace App\Policies;
use App\Post;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class PostPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any models.
*
* #param \App\User $user
* #return mixed
*/
public function viewAny(User $user)
{
//
}
/**
* Determine whether the user can view the model.
*
* #param \App\User $user
* #param \App\Post $post
* #return mixed
*/
public function view(User $user, Post $post)
{
//
}
/**
* Determine whether the user can create models.
*
* #param \App\User $user
* #return mixed
*/
public function create(User $user)
{
//
}
/**
* Determine whether the user can update the model.
*
* #param \App\User $user
* #param \App\Post $post
* #return mixed
*/
public function update(User $user, Post $post)
{
//
}
/**
* Determine whether the user can delete the model.
*
* #param \App\User $user
* #param \App\Post $post
* #return mixed
*/
public function delete(User $user, Post $post)
{
//
}
/**
* Determine whether the user can restore the model.
*
* #param \App\User $user
* #param \App\Post $post
* #return mixed
*/
public function restore(User $user, Post $post)
{
//
}
/**
* Determine whether the user can permanently delete the model.
*
* #param \App\User $user
* #param \App\Post $post
* #return mixed
*/
public function forceDelete(User $user, Post $post)
{
//
}
}
Modify the rules for each action, so for example we need to specify that only the admin or the post owner can update a post, so
public function update(User $user, Post $post)
{
if ($user->role === 'admin') {
return true;
}
return $post->user_id === $user->id;
}
And then register the policy
https://laravel.com/docs/8.x/authorization#registering-policies
<?php
namespace App\Providers;
use App\Models\Post;
use App\Policies\PostPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
Post::class => PostPolicy::class,
];
/**
* Register any application authentication / authorization services.
*
* #return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
And finally authorize your controller, add this line to the constructor
public function __construct()
{
$this->authorizeResource(Post::class, 'post');
}
Note that the 2nd parameter in the function call is the name of the route parameter, post is going to be your route parameter if you created the a resourceful controller
If you are not using a resourceful controller, or want to authorize actions manually, then you can use without adding the above line in the constructor
https://laravel.com/docs/8.x/authorization#via-controller-helpers
public function update(Request $request, Post $post)
{
$this->authorize('update', $post);
// The current user can update the blog post...
}
the first parameter is the name of the policy method, and the 2nd paramter is the post object

How do I extend Laravel Sanctum's functionality?

I am specifically trying to get Sanctum's Guard class to look for the API token in a JSON request body if it can't find it in the Authorization header. I simply need to add an elseif after it checks for the bearer token.
So question is: What is the best way to override this method (or class) with my own, without touching the original Sanctum files?
<?php
namespace Laravel\Sanctum;
use Illuminate\Contracts\Auth\Factory as AuthFactory;
use Illuminate\Http\Request;
class Guard
{
/**
* The authentication factory implementation.
*
* #var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* The number of minutes tokens should be allowed to remain valid.
*
* #var int
*/
protected $expiration;
/**
* Create a new guard instance.
*
* #param \Illuminate\Contracts\Auth\Factory $auth
* #param int $expiration
* #return void
*/
public function __construct(AuthFactory $auth, $expiration = null)
{
$this->auth = $auth;
$this->expiration = $expiration;
}
/**
* Retrieve the authenticated user for the incoming request.
*
* #param \Illuminate\Http\Request $request
* #return mixed
*/
public function __invoke(Request $request)
{
if ($user = $this->auth->guard('web')->user()) {
return $this->supportsTokens($user)
? $user->withAccessToken(new TransientToken)
: $user;
}
if ($token = $request->bearerToken()) {
$model = Sanctum::$personalAccessTokenModel;
$accessToken = $model::where('token', hash('sha256', $token))->first();
if (! $accessToken ||
($this->expiration &&
$accessToken->created_at->lte(now()->subMinutes($this->expiration)))) {
return;
}
return $this->supportsTokens($accessToken->tokenable) ? $accessToken->tokenable->withAccessToken(
tap($accessToken->forceFill(['last_used_at' => now()]))->save()
) : null;
}
}
/**
* Determine if the tokenable model supports API tokens.
*
* #param mixed $tokenable
* #return bool
*/
protected function supportsTokens($tokenable = null)
{
return in_array(HasApiTokens::class, class_uses_recursive(
$tokenable ? get_class($tokenable) : null
));
}
}
I don't know if you've already figured out but I think you need to add an entry in your AppServiceProvider boot method and override configureGuard functionality placed in SanctumServiceProvider at line 94.
app/Providers/AppServiceProvider.php
Auth::resolved(function ($auth) {
$auth->extend('sanctum', function ($app, $name, array $config) use ($auth) {
return tap($this->createGuard($auth, $config), function ($guard) {
$this->app->refresh('request', $guard, 'setRequest');
});
});
});
You will also need to override createGuard function to specify your custom Guard class with the functionality you require.

PHP/Laravel - Extending authorizeResource to work on custom method

I have a resource controller called StreamController.php, that utilizes a policy called StreamPolicy.php.
In my controller, I have this:
//StreamController.php
/**
* Construct method.
*/
public function __construct()
{
$this->middleware('auth');
$this->authorizeResource(Stream::class, 'stream');
}
With above, all the RESTful endpoints is successfully "protected" using the policy.
However, I have added a new method to my controller, called documents(), like so:
//web.php
Route::get('streams/{stream}/documents', 'StreamController#documents');
//StreamController.php
/**
* Display the imported documents of the resource
*
* #return \Illuminate\Http\Response
*/
public function documents(Stream $stream)
{
return view('streams.documents', compact('stream'));
}
Now the problem is if I visit the URL:
example.com/streams/1 and I am not the owner of the stream, I get a 403 page - but if I go to:
example.com/streams/1/documents and I am not the owner of the stream, I can still access the page.
What am I doing wrong? How can I make so my policy also covers the documents() methods in my controller?
Edit:
This is my StreamPolicy.php file:
//StreamPolicy.php
namespace App\Policies;
use App\User;
use App\Stream;
use Illuminate\Auth\Access\HandlesAuthorization;
class StreamPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view the stream.
*
* #param \App\User $user
* #param \App\Stream $stream
* #return mixed
*/
public function view(User $user, Stream $stream)
{
return $user->id == $stream->user_id;
}
/**
* Determine whether the user can create streams.
*
* #param \App\User $user
* #return mixed
*/
public function create(User $user)
{
//
return true;
}
/**
* Determine whether the user can update the stream.
*
* #param \App\User $user
* #param \App\Stream $stream
* #return mixed
*/
public function update(User $user, Stream $stream)
{
//
return $user->id == $stream->user_id;
}
/**
* Determine whether the user can delete the stream.
*
* #param \App\User $user
* #param \App\Stream $stream
* #return mixed
*/
public function delete(User $user, Stream $stream)
{
//
return $user->id == $stream->user_id;
}
/**
* Determine whether the user can restore the stream.
*
* #param \App\User $user
* #param \App\Stream $stream
* #return mixed
*/
public function restore(User $user, Stream $stream)
{
//
}
/**
* Determine whether the user can permanently delete the stream.
*
* #param \App\User $user
* #param \App\Stream $stream
* #return mixed
*/
public function forceDelete(User $user, Stream $stream)
{
//
}
}
Controller.php uses "AuthorizesRequest" trait which defines below 2 methods:
trait AuthorizesRequests
{
/**
* Get the map of resource methods to ability names.
*
* #return array
*/
protected function resourceAbilityMap()
{
return [
'show' => 'view',
'create' => 'create',
'store' => 'create',
'edit' => 'update',
'update' => 'update',
'destroy' => 'delete',
];
}
/**
* Get the list of resource methods which do not have model parameters.
*
* #return array
*/
protected function resourceMethodsWithoutModels()
{
return ['index', 'create', 'store'];
}
You can override these 2 protected methods per controller basis because every controller extends Controller.php
class UserController extends Controller
{
public function __construct ()
{
$this->authorizeResource ( User::class, 'user' );
}
/**
* Get the map of resource methods to ability names.
*
* #return array
*/
protected function resourceAbilityMap()
{
return [
'show' => 'view',
'create' => 'create',
'store' => 'create',
'edit' => 'update',
'update' => 'update',
'destroy' => 'delete',
'customMethod'=>'customMethod',
'customMethodWithoutModel'=>'customMethodWithoutModel'
];
}
/**
* Get the list of resource methods which do not have model parameters.
*
* #return array
*/
protected function resourceMethodsWithoutModels()
{
return ['index', 'create', 'store','customMethodWithoutModel'];
}
Its Policy Class
class UserPolicy
{
/**
* Determine whether the user can custom method.
*
* #param \App\User $user
* #param \App\User $model
* #return mixed
*/
public function customMethod(User $user, User $model){
return true;
}
/**
* Determine whether the user can custom method without model.
*
* #param \App\User $user
* #return mixed
*/
public function customMethodWithoutModel(User $user){
return true;
}
I don't know exactly why is not working but I'm afraid that the authorizeResource method only handles the routes for the well-known resources end-points: view, create, update, delete and restore.
Later edit: Take a look in the docs to see which are the actions handled by the Resource Controllers https://laravel.com/docs/5.7/controllers#resource-controllers
What you should do is to explicitly set the authorization to the new route:
Route::get('streams/{stream}/documents', 'StreamController#documents')->middleware('can:documents,stream');
Of course, the documents method should exist on the StreamPolicy class.
OR
To authorize inside the StreamController.documents method:
public function documents(Stream $stream)
{
$this->authorize('documents', $stream);
return view('streams.documents', compact('stream'));
}

Unable to get login using laravel 5.4

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,
],
],
];

Categories