Facebook Login authentication using PHP SDK doesn't work properly? - authentication

When a user comes to my site, i used to open a new window to authenticate the user and ask for permission through my app(call it as UseCase1). But when a user is already logged-in i was trying to fetch the logged-in user info through PHP SDK so that i need not open a new window and check for the same(You will be avoiding opening a new window that closes after a while since the user is already logged in). But the getUser() method doesn't return me anything. The same method works fine when i go through the UseCase1(open new window which closes automatically).
Below is the code i am trying to use:
$facebook = new Facebook(array(
'appId' => $appId,
'secret' => $appSecret,
'oauth' => true
));
$me = $facebook->getUser();
if ($me) {
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
//code to redirect to login url
// USECASE1
// use $facebook->getUser() one USECASE1 is over
// now the user info is generated properly
}
}
All the times the user is going through USECASE1(but with an empty window since user is logged in and already authenticated the app) even though he is already logged-in and already authenticated the app previously.
Any idea why this is happening

In your code, if the user is getting to 'USECASE1', then it shows that '$me' is being set, because it is getting to your try/catch.
Using $me = $facebook->getUser(); is not a test for whether a user has accepted permissions for your application yet.
I suspect that the reason for the 'FacebookApiException' Exception being thrown is because you haven't got your user permissions yet.
I'd suggest reading the authentication flow and the example PHP SDK authentication flow, see the following links:
http://developers.facebook.com/docs/reference/php/facebook-api/
http://developers.facebook.com/docs/authentication2/

Related

ServiceStack Authentication IsAuthenticated always false for users authenticated via facebook

Hi am trying to use OAuth authentication FacebookAuthProvider provided by servicestack
var AppSettings = appHost.AppSettings;
appHost.Plugins.Add(new AuthFeature(() => new CustomUserSession(),
new IAuthProvider[] {
new CredentialsAuthProvider(AppSettings),
new FacebookAuthProvider(AppSettings),
new GoogleAuthProvider(AppSettings)
}));
I have implement custom AuthEvents and I have access to authorized user data
but after RedirectUrl happens in endpoint session is empty and IsAuthenticated property is false
In the same time from Controller I can see that created session successfully saved in Cache
This scenario occurred only if user doesn't login in facebook in the browser yet, but for user that already logged in facebook, authentication works fine
What am I doing wrong ?
Thanks in advance!
Updates:
Scenario for repsoducing:
ensure that you didn't loged in facebook in browser (open facebook.com and log out if need)
run web app (project which created with template mvcauth)
try to login via facebook
3.1. for first attempt you will be redirected to https://www.facebook.com/login.php? page for specify your facebook account credentials
after first attempt you will be returned to web app page /Account/Login#s=1 but User.Identity.IsAuthenticated = false in AccountController.Login and you still unauthorized.
after second attempt you will finally successfully logged in
At the same time after first attempt Session with user data will be created and saved in Cache, it looks like after redirecting from page 'https://www.facebook.com/login.php' а new session being created without auth data, but for second attempt we successfully login, maybe the core of issue is redirection from 'https://www.facebook.com/login.php'
In order to be able to use ServiceStack.Auth in MVC and vice-versa you'll need to register the NetCoreIdentityAuthProvider which provides integration between ServiceStack Authenticated Sessions and ASP.NET Core's Claims Principal, e.g:
public void Configure(IAppHost appHost)
{
var AppSettings = appHost.AppSettings;
appHost.Plugins.Add(new AuthFeature(() => new CustomUserSession(),
new IAuthProvider[] {
new NetCoreIdentityAuthProvider(AppSettings), /* Use ServiceStack Auth in MVC */
new CredentialsAuthProvider(AppSettings), /* Sign In with Username / Password */
new FacebookAuthProvider(AppSettings),
new GoogleAuthProvider(AppSettings),
new MicrosoftGraphAuthProvider(AppSettings),
}));
appHost.Plugins.Add(new RegistrationFeature()); //Enable /register Service
//override the default registration validation with your own custom implementation
appHost.RegisterAs<CustomRegistrationValidator, IValidator<Register>>();
}

Logging out the user from other computers (that he logged in before) when he logs in from another computer

I have a web application that employees log in to do stuff. What Im trying to achieve is: When a user logs in from a computer, if he is already logged in on another computer, that must be logged out. The web app is MVC Asp.Net Core 2.2 Code first. I have added a signInManager in startup and edited the PasswordSignInAsync method. I login the system from two different devices. When I click something on the screen from the first computer that I loggedin, it redirects to logout. It seems like working. But Im not sure if this is the right way of doing this. The code I added is: await UserManager.UpdateSecurityStampAsync(user); Inside PasswordSignInAsync method.
Inside the startup class ConfigureServices method I added
'services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddSignInManager<SignInManagerX>()'
Then in SignInManagerX class which is inherited from SignInManager I overrided the PasswordSignInAsync
public override async Task<SignInResult>
PasswordSignInAsync(ApplicationUser user, string password,
bool isPersistent, bool lockoutOnFailure)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
var attempt = await CheckPasswordSignInAsync(user, password,
lockoutOnFailure);
//Here is added
if (attempt.Succeeded)
{
await UserManager.UpdateSecurityStampAsync(user);
}
//Add end
return attempt.Succeeded
? await SignInOrTwoFactorAsync(user, isPersistent)
: attempt;
}
Is this the right way ? or I should add a table to db for logins which holds the info if the user is already logged in on another Ip. Then Logging out that user from all computers if the last and current login attempt is true ?
Yes , the primary purpose of the SecurityStamp is to enable sign out everywhere.
The basic idea is that whenever something security related is changed on the user, like a password, it is a good idea to automatically invalidate any existing sign in cookies, so if your password/account was previously compromised, the attacker no longer has access.
Reference : https://stackoverflow.com/a/19505060/5751404
You can set validateInterval to TimeSpan.Zero for immediate logout .

Laravel 4 Auth::attempt($userdata, false) authentication is still kept

Recently I have decided to add a "remember me" feature to my Laravel 4 app.
Appropriate method with syntaxis was found:
Auth::attempt(array $credentials = array(), $remember = false)
This was adopted for my needs like so:
Auth::attempt($userdata, Input::has('remember'))
Application kept the Auth session, and the user was authenticated even after browser was closed.
Although, I have found out that now Laravel always keeps a user authenticated, no matter what state "remember" checkmark is.
I have tried to do:
Auth::attempt($userdata, false)
and
Auth::attempt($userdata,)
User was still authenticated across the browser sessions!!!
Now, since Auth::attempt($userdata) not keeping the auth session, I felt that whenever there is an indications of the second argument in Auth::attempt method, Laravel auto assumes it as "true".
Can anyone clarify that?
EDIT:
To make it a super clear to everyone, I will list the steps to recreate this behaviour:
Logout of the app Auth::logout();
Login again Auth::attempt($userdata, false)
Close and open the browser
Go to the app url.
Application is loaded authenticated
This is my first question here, so please, be patient with me :)
EDIT : OP made clear he called Auth::logout() properly, so answer is edited to include the "Real" answer.
Set lifetime value in app/config/session/php to 0 to make cookie clear on browser close.
Previous answer
This is the login method in Illuminate\Auth\Guard (Which is facaded to Auth) class, which is eventually called by Auth::attempt().
source : http://laravel.com/api/source-class-Illuminate.Auth.Guard.html#263-291
public function login(UserInterface $user, $remember = false)
{
$id = $user->getAuthIdentifier();
$this->session->put($this->getName(), $id);
// If the user should be permanently "remembered" by the application we will
// queue a permanent cookie that contains the encrypted copy of the user
// identifier. We will then decrypt this later to retrieve the users.
if ($remember)
{
$this->queuedCookies[] = $this->createRecaller($id);
}
// If we have an event dispatcher instance set we will fire an event so that
// any listeners will hook into the authentication events and run actions
// based on the login and logout events fired from the guard instances.
if (isset($this->events))
{
$this->events->fire('auth.login', array($user, $remember));
}
$this->setUser($user);
}
It is clear that even though the cookie is set when $remember is set to true, the cookie itself is not cleared when $remember is set to false or other non-truthy value.
The cookie is cleared when you call Auth::logout() function.

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.

Facebook PHP SDK 3.0 (check if user is logged in)

I'm trying to use the Facebook PHP SDK 3.0 to be able to know if a user is currently logged on into his facebook account to display his information.
This is the flow:
User comes to my site and connects his account with my facebook app.
User is now logged in on my site, my site can access his information.
User logs out of facebook.com.
User refreshes my page.
User is logged out of my site.
User logs in on facebook.com.
User refreshes my page.
USER SHOULD BE LOGGED IN ON MY SITE BUT ISN'T.
When you use the Javascript SDK, you can check if user is logged in and everything works fine with the steps. What needs to be done with the PHP SDK 3.0? I don't want to give access_offline permissions, I just want to be able to access the user when he's logged in on facebook.com.
Thanks a lot,
Jeremie
Add this javascript in all pages(core js).
login() and logout() are functions for your system login and logout.
By this it will check every time fb is logged in or not and call function for login.
And will satisfy condition -
USER SHOULD BE LOGGED IN ON MY SITE BUT ISN'T.
<script type="text/javascript">
window.fbAsyncInit = function() {
FB.init({appId: '113700398662301', status: true, cookie: true, xfbml: true});
/* All the events registered */
FB.Event.subscribe('auth.login', function(response) {
// do something with response
login();
});
FB.Event.subscribe('auth.logout', function(response) {
// do something with response
logout();
});
FB.getLoginStatus(function(response) {
if (response.session) {
// logged in and connected user, someone you know
login();
}
});
};
</script>
based on the signed request, u should be able to know if the user has authorized your app before.
This should give u some status about the user.
to check if he is logged in to fb, for authorized user, u can try to query "/me" and see if you can query it successfully