Laravel, how to run legacy & jetstream process login when using google callback - google-oauth

We trying to migrate an old manager (legacy) to Laravel,
we made all a process using Jetstream to log, and Fortify::authenticateThrough to run some necessary code for always running legacy manager (because there is a lot of interface to migrate, and we migrating step by step old interface).
I tried to include login with google email, all good for Jetstream (using Socialite)
In Jetstream Provider, we having something like :
public function boot()
{
$this->configurePermissions();
Jetstream::deleteUsersUsing(DeleteUser::class);
// Legacy operations for sessions
Fortify::authenticateThrough(function (Request $request) {
return array_filter([
config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null,
LegacyPrepareAuthenticatedSession::class,
AttemptToAuthenticate::class,
PrepareAuthenticatedSession::class,
]);
});
}
I follow a tuto for using Socialite, and on callback google, we having :
public function handleGoogleCallback(Request $request)
{
try {
$user = Socialite::driver('google')->user();
$finduser = User::where('google_id', $user->id)->first();
if($finduser){
$test = Auth::login($finduser);
// Legacy operations for sessions
// we tried this but it don't lunch LegacyPrepareAuthenticatedSession
$test = (new Pipeline(app()))->send($request)->through(array_filter([
config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null,
LegacyPrepareAuthenticatedSession::class,
AttemptToAuthenticate::class,
PrepareAuthenticatedSession::class,
]));
return redirect('/lecacy');
}else{
die('user not find');
}
//catch exceptions
} catch (Exception $e) {
dd($e->getMessage());
}
}
LegacyPrepareAuthenticatedSession start some session variable necessary for legacy manager.
I can't find a way to lunch the LegacyPrepareAuthenticatedSession on callback google
I would like find a way to use what jetstream lunch for keeping the same pipeline between the login with jetstream and google auth.
Is there a way to lunch it when log with google ?
Thanks a lot.

Related

Laravel Socialite for Mobile APPs using APIs

I'm using Laravel Socialite package for social media (Facebook, Gmail) authentication, creating account and login on website and work fine.
Now I'm in need of providing same feature on mobile devices but I'm not getting any helpful lead so far about how and what needs to be done in this case.
I've users table which store user's information and social_providers table which store user_id and provider_id returned by the socialite using below code.
public function handleProviderCallback(Request $request, $provider = null) {
try {
$socialUser = Socialite::driver($provider)->user();
} catch (\Exception $e) {
return redirect('/');
}
//check if we have logged provider
$socialProvider = SocialProvider::where('provider_id', $socialUser->getId())->first();
if (!$socialProvider) {
$name = explode(' ', $socialUser->getName(), 2);
$first_name = $name[0];
$last_name = $name[1];
//create a new user and provider
$user = User::firstOrCreate(
['email' => $socialUser->getEmail()], ['last_name' => $last_name,
'first_name' => $first_name,
'email_verified_at' => date('Y-m-d H:i:s')]
);
$user->socialProviders()->create(
['provider_id' => $socialUser->getId(), 'provider' => $provider]
);
} else {
$user = $socialProvider->user;
}
auth()->login($user);
return redirect('/');
}
Now in case of mobile, what needs to be done. Do I've to user android SDK on mobile and that will send user info and provider_id to backend? OR something needs to be done at backend Laravel side? Thanks if someone can guide me in basic way that what needs to be done and on which side (mobile or backend).
for the mobile app, you would need to use the Mobile SDK to get the access token and in the backend, you would need to use the access token to get user info like the following
$provider_user = Socialite::driver($provider)->userFromToken($request->access_token);

Why is the callback identifier not being invoked?

I'm trying to implement matching a Kerberos authentication with a local user database in CakePHP4. So I installed CakePHP 4 and the Authentication plugin 2.0. Since Kerberos auth is managed by our IIS WebServer, only thing I have to do is check if the authenticated user is known by my webapp.
The callback authentication should let me implement something like this, right ?
So I put this function in Application.php :
<?php
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
$service = new AuthenticationService();
// Define where users should be redirected to when they are not authenticated
$service->setConfig([
'unauthenticatedRedirect' => '/users/login',
'queryParam' => 'redirect',
]);
// Load the authenticators. Session should be first.
$service->loadAuthenticator('Authentication.Session');
$service->loadIdentifier('Authentication.Callback', [
'callback' => function($data) {
// do identifier logic
if (empty($_SERVER['REMOTE_USER'])) {
return new Result(
null,
Result::FAILURE_OTHER,
['message' => 'Unknown user.']
);
} else {
// On vérifie que l'utilisateur est autorisé à utiliser cette application
$users = TableRegistry::getTableLocator()->get('Users');
$remoteUserNoDomain = str_replace("DOMAIN\\", "", $_SERVER['REMOTE_USER']);
$result = $users->find()
->where(['username' => $remoteUserNoDomain]);
if ($result) {
return new Result($result, Result::SUCCESS);
}
return new Result(
null,
Result::FAILURE_OTHER,
['message' => 'Removed user.']
);
}
return null;
}
]);
return $service;
}
But so far, it doesn't seem to work, like it won't call the callback function at all. I tried to put some debug code, exits... Nothing works.
I would assume that you've also done all the other required configuring for authentication to work, ie loading the plugin, adding the authentication middleware, etc.!?
https://book.cakephp.org/authentication/2/en/index.html
That said, identifiers do not do any work on their own, they are being triggered by authenticators in case they actually require them. You only have the Session authenticator loaded, which in its default configuration doesn't make use of identifiers, but even if you configure it to use identifiers (by setting its identify option to true), it will only use them when there already is an identity in the session, then the identifier is being used to validate that identity.
https://github.com/cakephp/authentication/blob/2.3.0/src/Authenticator/SessionAuthenticator.php#L52
I'm not familiar with Kerberos authentication, but if it pre-populates $_SERVER['REMOTE_USER'] (btw. never access superglobals in CakePHP directly, it will only cause trouble down the road), then what you need is a custom authenticator. You could then re-use the password identifier for the ORM access part, as it allows finding something without checking the password (weirdly enough, given its name).
Quick and dirty example based on your snippet:
// src/Authenticator/KerberosAuthenticator.php
namespace App\Authenticator;
use Authentication\Authenticator\AbstractAuthenticator;
use Authentication\Authenticator\Result;
use Authentication\Authenticator\ResultInterface;
use Psr\Http\Message\ServerRequestInterface;
class KerberosAuthenticator extends AbstractAuthenticator
{
public function authenticate(ServerRequestInterface $request): ResultInterface
{
$server = $request->getServerParams();
if (empty($server['REMOTE_USER'])) {
return new Result(null, Result::FAILURE_CREDENTIALS_MISSING);
}
$remoteUserNoDomain = str_replace("DOMAIN\\", "", $server['REMOTE_USER']);
$user = $this->_identifier->identify(['username' => $remoteUserNoDomain]);
if (empty($user)) {
return new Result(
null,
Result::FAILURE_IDENTITY_NOT_FOUND,
$this->_identifier->getErrors()
);
}
return new Result($user, Result::SUCCESS);
}
}
Your service authenticator/identifier setup would then look like this:
$service->loadAuthenticator('Authentication.Session');
$service->loadAuthenticator('Kerberos');
$service->loadIdentifier('Authentication.Password');
Nore sure if you'd then really want to use the session authenticator like that though, ie whether you only want to identify the remote user once per session.

Detecting if someone is logged into Meteor from a regular Node.js application

Is there a way for me to check to see if someone is logged into Meteor from outside of Meteor; for example, from an Express.js application? I would like to know from the Express app who the currently logged in user is on a particular client so that if the API were called, we would know who to apply the results of the API call to.
So this is best done it two parts.
A method to check whether the user is online in meteor
You can probably do it with a meteor smart package (community package repo) : https://github.com/erundook/meteor-profile-online
Make sure you have meteorite, installed via npm install meteorite -g
In your package repo use : mrt add profile-online
Accessing meteor's data using Express
To access the stuff in Express you would need a DDP client, I know this one works with pre1 (The version of DDP with Meteor 0.57+): https://github.com/EventedMind/node-ddp-client
You can have a method that checks for you in meteor
Server js (Meteor)
Meteor.methods({
'isonline: function(id) {
return Meteor.users.find(id).profile.online;
}
}
Express:
var client = new DDPClient({
host: "localhost",
port: 3000
});
userid = '1' //The user _id of the person you want to check
client.connect(function () {
console.log("Connected to Meteor at localhost:3000");
client.call("isonline", [userid], function(err,result) {
client.close();
if(!err) {
if(result) {
console.log("User " + userid + " is online");
}
else
{
console.log("That user isn't online");
}
}
else
{
console.log(err)
}
});
});

What is a good way to implement a custom authentication in Firebase?

I've done some things using firebase (so cool).
I'm doing the custom login, I've generated a AUTH_TOKEN (using nodejs).
My question is if I need to pass in all my page that I wanna to protect the code below?
Peace,
Tulio Cruz
var dataRef = new Firebase("https://example.firebaseio.com");
// Log me in.
dataRef.auth(AUTH_TOKEN, function(error, result) {
if(error) {
console.log("Login Failed!", error);
} else {
console.log('Authenticated successfully with payload:', result.auth);
console.log('Auth expires at:', new Date(result.expires * 1000));
}
});
I'm not sure I fully understand your question. If you want to know if you need to call auth every time a page is loaded -- yes you do. When using custom login with the low-level auth() api call, we don't do any session management for you.
You only need to call auth() once per page load though -- not once for each Firebase reference.

how to retrieve login status while using offline_access

I'm facing a little problem because of the offline_access permission I'm requesting for my website.
I'm using the code that is given in the documentation in order to define if someone is logged or not :
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
$user = null;
}
}
But as I have an offline access, it seems that I'm always having a value for $user. So how can i log out someone from my website ?
Is there any way to retrieve a status via the php SDK ?
Thanks for the help,
Stéphane
In PHP try using GetLogoutUrl and sending the user there. You can also call the JS FB.logout() call from client-side. If you want to remove the app from the user, call HTTP delete to me/permissions.