I have 5 projects which are successfully deployed.... i need to give access to the user by single login to all these projects...
For example : I have 5 web app seprately which are deployed as
https://example.com/project1
https://example.com/project2
https://example.com/project3
https://example.com/project4
https://example.com/project5
and have their separate sql...
I need to login the user at very first and then the user can access all these web app and their working should go on with their respective sql....
these projects are created on laravel so, Right now the laravel auth is working and they have their own login system
All i need is to login user once and they can access all these apps
and user should login with 6th SQL(means another SQL)
In same situation, i made one more project only for authentification with Laravel Passport and add this project as socialite provider to other applications.
With this flow you have one entry point and user management for all projects.
First - make auth project. You need Laravel and Laravel Passport. See docs here. Optional - make user management ui (adding, removing, etc). Goal - users can login with their login/password.
Second - add ability to login for other projects with laravel/socialite.
Install laravel/socialite and socialiteproviders/manager
Create your own provider for your auth project - to example see the docs in socialiteproviders/manager
Implement LoginController in your apps for socialite. Some example:
class LoginController extends Controller
{
// Custom service for work with socialite - create or find users, etc
private SocialiteService $service;
public function __construct(SocialiteService $service)
{
$this->middleware('guest')->except(['logout', 'callback']);
$this->service = $service;
}
public function showLoginForm()
{
return view('pages.login');
}
public function login()
{
return $this->service->redirectToAuth();
}
public function callback(Request $request)
{
try{
$user = $this->service->getUser($request);
auth()->login($user);
return redirect()->route('index');
}catch (SocialiteException $exception){
return redirect()->route('login')->withErrors([
'error' => $exception->getMessage(),
'error_description' => $exception->getErrorDescription()
]);
}
}
public function logout(Request $request)
{
auth()->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect()->route('login');
}
}
And after that you have SSO for all your apps with dedicated auth service.
Hint: create a private package with provider, service and all you auth logic. With this you can simply add this auth flow to feature projects and avoid duplicated code.
Related
I am using policies to prevent users from accessing the admin panel. Only admins can be able to access the admin panel. I have created the policies and registered them in the authservice provider. The problem is when an admin logins in they are still not able to view the admin panel and instead, they return the 403 pages. where have I gone wrong?
the route in the web.php
Route::group(['prefix'=>'admin','middleware'=>(['auth','can::acessAdmins'])],function(){
Route::resource('dashboard',AdminDashboard_Controller::class);
}
the helper functions in the user model
public function hasAnyRoles($roles){
return $this->roles()->wherein('Role_name',$roles)
->first()?true:false;
}
public function hasRole($role){
return $this->roles()->wherein('Role_name',$role)
->first()?true:false;
}
Admin access policy
public function accessAdmins(user $user){
return $user->hasAnyRoles(['SuperAdmin','NormalAdmin']);
}
public function manageAdmins(user $user){
return $user->hasAnyRoles(['SuperAdmin']);
}
You should change the route to this:
Route::group(['prefix'=>'admin','middleware'=>(['auth','can:accessAdmins'])],function(){
Route::resource('dashboard',AdminDashboard_Controller::class);
}
The can::accessAdmins to can:accessAdmins, multiple typos.
Also see https://laravel.com/docs/8.x/middleware#middleware-parameters for more information on parameters.
And besides that you should make sure that the authorized user has the right roles.
I am looking for a good tutorial or advice on how to redirect after authenticated based on roles in laravel 8 fortify without jetstream. I have found one that says to create a new LoginResonse.php in App\Http\Responses\loginresponse.php which I did but I am not sure where to register this new response because the tutorial I am using says to do it in Jetstreamserviceprovider but I am not using Jetstream. Any ideas?
You will want to register your custom LoginResponse in the FortifyServiceProvider, specifically the boot method.
public function boot()
{
$this->app->singleton(
\Laravel\Fortify\Contracts\LoginResponse::class,
\App\Http\Responses\LoginResponse::class
);
}
This registers your custom LoginResponse with Laravels IoC service container and informs Laravel to provide your LoginResponse to methods that require an instance of an object which implements the LoginResponse from Fortify.
Inside your custom LoginResponse and in the toResponse method, you can perform whatever logic you require. For example;
public function toResponse($request)
{
if ($request->wantsJson()) {
return response()->json(['two_factor' => false]);
}
if (Auth::user()->hasRole('admin') {
return redirect(route('admin.index'));
}
}
I am using Passport to log in users to a Laravel API endpoint, users get authenticated using their social accounts (google, facebook) using laravel-socialite package.
the workflow of logging users in and out works perfectly (generating tokens...Etc). The problem is I have a controller that should return data based on whether there is a user logged in or not.
I do intercept the Bearer token from the HTTP request but I couldn't get the user using the token (I would use DB facade to select the user based on the token but I am actually looking whether there is a more clean way already implemented in Passport)
I also don't want to use auth:api middleware as the controller should work and return data even if no user is logged in.
this is the api route:
Route::get("/articles/{tag?}", "ArticleController#get_tagged");
this is the logic I want the controller to have
public function get_tagged($tag = "", Request $request)
{
if ($request->header("Authorization"))
// return data related to the user
else
// return general data
}
Assuming that you set your api guard to passport, you can simply call if (Auth::guard('api')->check()) to check for an authenticated user:
public function get_tagged($tag = "", Request $request)
{
if (Auth::guard('api')->check()) {
// Here you have access to $request->user() method that
// contains the model of the currently authenticated user.
//
// Note that this method should only work if you call it
// after an Auth::check(), because the user is set in the
// request object by the auth component after a successful
// authentication check/retrival
return response()->json($request->user());
}
// alternative method
if (($user = Auth::user()) !== null) {
// Here you have your authenticated user model
return response()->json($user);
}
// return general data
return response('Unauthenticated user');
}
This would trigger the Laravel authentication checks in the same way as auth:api guard, but won't redirect the user away. In fact, the redirection is done by the Authenticate middleware (stored in vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php) upon the failure of the authentication checking.
Beware that if you don't specify the guard to use, Laravel will use the default guard setting in the config/auth.php file (usually set to web on a fresh Laravel installation).
If you prefer to stick with the Auth facade/class you can as well use Auth::guard('api')->user() instead or the request object.
thanks to #mdexp answer
In my case I can resolve my problem with using
if (Auth::guard('api')->check()) {
$user = Auth::guard('api')->user();
}
In my controller.
I am involved in a web site using Laravel 5.4 and using the built-in authentication.
I have added a "Forgot Password" link that shows the ResetPasswordController#showLinkRequestForm which emails a password
reset link when submitted and then the ResetPasswordController#showResetForm redirects to the login page when submitted.
The problem I have is that we have two different Users - clients and admins. I have the ability to determine which is
which through the registered email address but I want the redirect following password reset be different for each type
(client = '/' and admin = '/admin').
How is this be done?
If you are using the ResetsPasswords trait in your controller, you can create your own redirectTo() method which will be called to redirect the user :
// import the needed trait
use Illuminate\Foundation\Auth\ResetsPasswords;
class YourResetPasswordController {
// use the needed trait
use ResetsPasswords;
// override the method that redirects the user
public function redirectTo()
{
if (auth()->user()->isAdmin()) {
return redirect('/admin');
} else {
return redirect('/');
}
}
}
Let me know if it helped you :)
Does laravel provide a way to prevent multiple logins of a user from different devices / browsers at a given time? If yes then how can i force a user to logged in from a single device at a single time. I am developing a online quiz app using laravel 5.6 where users can logged in from a single place and take test.
laravel provide this method to invalidating and "logging out" a user's sessions that are active on other devices logoutOtherDevices()
to work with this method you need also to make sure that the
Illuminate\Session\Middleware\AuthenticateSession
middleware is present and un-commented in your app/Http/Kernel.php class' web middleware group:
'web' => [
// ...
\Illuminate\Session\Middleware\AuthenticateSession::class,
// ...
],
then you can use it like this
use Illuminate\Support\Facades\Auth;
Auth::logoutOtherDevices($password);
Perhaps this should get you started:
Add a column in users_table.php
$table->boolean('is_logged_in')->default(false);
When a user logs in: LoginController.php
public function postLogin()
{
// your validation
// authentication check
// if authenticated, update the is_logged_in attribute to true in users table
auth()->user()->update(['is_logged_in' => true]);
// redirect...
}
Now, whenever a user tries to login from another browser or device, it should check if that user is already logged in. So, again in LoginController.php
public function index()
{
if (auth()->check() && auth()->user()->is_logged_in == true) {
// your error logic or redirect
}
return view('path.to.login');
}
When a user logs out: LogoutController.php
public function logout()
{
auth()->user()->update(['is_logged_in' => false]);
auth()->logout();
// redirect to login page...
}