Comments (6)
@kaizirlewagen What are you missing is you need to use TwoFactorScreenAuthenticatable
as a trait within Screen
Basically the whole setup process is
- Install Laravel Fortify package
composer require laravel/fortify
- Publish its resources
php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
- Run migrations to add two_fa columns
php artisan migrate
- Add FortifyServiceProvider into
providers
array withinconfig/app.php
(I lost 15 minutes of my life when forget to do this in a first time :) - Add
TwoFactorAuthenticatable
trait to User model
use Laravel\Fortify\TwoFactorAuthenticatable;
class User extends Authenticatable
{
use TwoFactorAuthenticatable;
}
- Install Orchid Fortify
composer require orchid/fortify
-
Set to
false
auth
key ofconfig/platform.php
-
Within required Screen (for example,
UserProfileScreen
add following lines
use Orchid\Screen\Screen;
use Orchid\Fortify\TwoFactorScreenAuthenticatable;
class UserProfileScreen extends Screen
{
use TwoFactorScreenAuthenticatable; // I guess this is where you've been stacked
public function commandBar(): iterable
{
return [
$this->twoFactorCommandBar(), // dropdown button
];
}
public function layout(): iterable
{
return [
// other layouts
$this->twoFactorLayout(), // modal and methods
];
}
}
- Almost done, BUT it is still needs extra actions to be done to work
Fortify provides some options - one of them is to confirm Two FA or not. You may find this within config/fortify.php
'features' => [
Features::twoFactorAuthentication([
'confirm' => true, // confirm Two FA
'confirmPassword' => true, // confirm password to enable Two FA
]),
],
confirm
key requires to you to confirm TwoFA. If TwoFA keys was not confirmed you still be able to login without TwoFA.
Or you may just disable it (
'confirm' => false
) if you're ok with no confirmation - it is will work
You may achieve this as you wish, I will show "my way"
- Create Layout for confirmation code
use Orchid\Screen\Field;
use Orchid\Screen\Fields\Input;
use Orchid\Screen\Layouts\Rows;
class ProfileTwoFALayout extends Rows
{
protected function fields(): iterable
{
return [
Input::make('code'), // key should be named `code`. That's basically required minimum
];
}
}
- Add Layout to your Screen
class UserProfileScreen extends Screen
{
use TwoFactorScreenAuthenticatable; // I guess this is where you've been stacked
public function commandBar(): iterable
{
return [
$this->twoFactorCommandBar(), // dropdown button
];
}
public function layout(): iterable
{
return [
Layout::block(ProfileTwoFALayout::class)
->title(__('Confirm Two FA'))
->canSee(
auth()->user()->two_factor_secret && // show if authorized user has enabled Two FA
!auth()->user()->two_factor_confirmed_at // but still doesn't confirmed it
)
->commands(
Button::make(__('Confirm'))
->type(Color::PRIMARY())
->icon('check')
->action(route('two-factor.confirm')) // this route provided by Fortify and should not be changed
),
// other layouts
$this->twoFactorLayout(), // modal and methods
];
}
}
As you can see I implemented
canSee()
method to show this layout by specific condition. As I am using it only for user profile screen, I can useauth()->user()
with no fear. You app may require other logic to handle
After hitting confirm you will be redirect back, and in your database you will see all three columns two_factor_secret
, two_factor_recovery_code
and two_factor_confirmed_at
filled with information.
And that's it
from fortify.
It means that you need to add this trend and code to the UserProfileScreen
class
from fortify.
I edit "UserProfileScreen.php" and i add use Orchid\Fortify\TwoFactorScreenAuthenticatable;
and change the following functions:
* Button commands.
*
* @return Action[]
*/
public function commandBar(): iterable
{
return [
$this->twoFactorCommandBar(),
];
}
/**
* @return \Orchid\Screen\Layout[]
*/
public function layout(): iterable
{
return [
$this->twoFactorLayout(),
Layout::block(UserEditLayout::class)
->title(__('Profile Information'))
->description(__("Update your account's profile information and email address."))
->commands(
Button::make(__('Save'))
->type(Color::DEFAULT())
->icon('check')
->method('save')
),
Layout::block(ProfilePasswordLayout::class)
->title(__('Update Password'))
->description(__('Ensure your account is using a long, random password to stay secure.'))
->commands(
Button::make(__('Update password'))
->type(Color::DEFAULT())
->icon('check')
->method('changePassword')
),
];
}`
After that the following error is shown:
BadMethodCallException
Method App\Orchid\Screens\User\UserProfileScreen::twoFactorCommandBar does not exist.
Do you have an idea?
from fortify.
@czernika Amazing... thank you very much... i will try it today. 👍
from fortify.
@czernika Works perfect. Thx for your help 👍
from fortify.
I guess this should be added to README.md
I have followed the procedure above, filling some more information:
- Install Laravel Fortify package
composer require laravel/fortify
- Publish its resources
php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
- Run migrations to add two_fa columns
php artisan migrate
- Add FortifyServiceProvider into providers array within
config/app.php
Add App\Providers\FortifyServiceProvider::class
to providers
'providers' => ServiceProvider::defaultProviders()->merge([
/*
* Package Service Providers...
*/
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\FortifyServiceProvider::class,
])->toArray(),
- Add
TwoFactorAuthenticatable
trait to User modelapp\Models\User.php
use Laravel\Fortify\TwoFactorAuthenticatable;
class User extends Authenticatable
{
use TwoFactorAuthenticatable;
}
- Install Orchid Fortify
composer require orchid/fortify
-
Set to
false
theauth
key ofconfig/platform.php
-
Within required Screen - for example
UserProfileScreen
(app\Orchid\Screens\User\UserProfileScreen.php) add following lines
use Orchid\Screen\Screen;
use Orchid\Fortify\TwoFactorScreenAuthenticatable;
class UserProfileScreen extends Screen
{
use TwoFactorScreenAuthenticatable; // I guess this is where you've been stacked
public function commandBar(): iterable
{
return [
$this->twoFactorCommandBar(), // dropdown button
];
}
public function layout(): iterable
{
return [
// other layouts
$this->twoFactorLayout(), // modal and methods
];
}
}
- Almost done, BUT it is still needs extra actions to be done to work
Fortify provides some options - one of them is to confirm Two FA or not. You may find this within config/fortify.php
'features' => [
Features::twoFactorAuthentication([
'confirm' => true, // confirm Two FA
'confirmPassword' => true, // confirm password to enable Two FA
]),
],
confirm
key requires to you to confirm TwoFA. If TwoFA keys was not confirmed you still be able to login without TwoFA.
Or you may just disable it ('confirm' => false) if you're ok with no confirmation - it is will work
You may achieve this as you wish, I will show "my way"
Create Layout for confirmation code in new file app\Orchid\Screens\User\ProfileTwoFALayout.php
<?php
declare(strict_types=1);
namespace App\Orchid\Screens\User;
use Orchid\Screen\Field;
use Orchid\Screen\Fields\Input;
use Orchid\Screen\Layouts\Rows;
class ProfileTwoFALayout extends Rows
{
protected function fields(): iterable
{
return [
Input::make('code'), // key should be named `code`. That's basically required minimum
];
}
}
Add Layout to your Screen in app\Orchid\Screens\User\UserProfileScreen.php
class UserProfileScreen extends Screen
{
use TwoFactorScreenAuthenticatable; // I guess this is where you've been stacked
public function commandBar(): iterable
{
return [
$this->twoFactorCommandBar(), // dropdown button
];
}
public function layout(): iterable
{
return [
Layout::block(ProfileTwoFALayout::class)
->title(__('Confirm Two FA'))
->canSee(
auth()->user()->two_factor_secret && // show if authorized user has enabled Two FA
!auth()->user()->two_factor_confirmed_at // but still doesn't confirmed it
)
->commands(
Button::make(__('Confirm'))
->type(Color::PRIMARY())
->icon('check')
->action(route('two-factor.confirm')) // this route provided by Fortify and should not be changed
),
// other layouts
$this->twoFactorLayout(), // modal and methods
];
}
}
As you can see I implemented canSee()
method to show this layout by specific condition.
As I am using it only for user profile screen, I can use auth()->user() with no fear. You app may require other logic to handle
After hitting confirm
you will be redirect back, and in your database you will see all three columns two_factor_secret
, two_factor_recovery_code
and two_factor_confirmed_at
filled with information.
PROBLEM: OK, I can add 2FA to the user that has at least main privilege to access admin panel to reach his User Profile Screen and I can see all three fields in the database populated, and confirm
button is no longer visible in User Profile Screen, but I am not asked for 2FA on login?! What am I missing?
from fortify.
Related Issues (8)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fortify.