Laravel 5 socialize facebook login - facebook

I use auth login (out of the box). I have want to add Facebook login.
I have installed Socialize package, and In Auth/AuthController I added method fb:
public function fb()
{
return \Socialize::with('facebook')->redirect();
}
When I call http://ip/auth/fb its redirect me to http://ip/auth/login#=
Please help

First you need to create the FB project and you will have the client_id (App ID) and secret_key (App secret)
In your services configuration file: config/services.php you need to specify the facebook key like this:
'facebook' => [
'client_id' => 'client_id from fb',
'client_secret' => 'secret_key from fb',
'redirect' => 'http://your_site/your_fb_login_ok_path',
],
then you create the route:
Route::get('your_fb_login_ok_path', function ($facebook = "facebook")
{
// Get the provider instance
$provider = Socialize::with($facebook);
// Check, if the user authorised previously.
// If so, get the User instance with all data,
// else redirect to the provider auth screen.
if (Input::has('code'))
{
$user = $provider->user();
return var_dump($user);
} else {
return $provider->redirect();
}
});
This should do it.
Then remember to add this URL to your facebook redirect: http://your_site/your_fb_login_ok_path
That is the URL that FB will redirect you to after successful login.

There are a number of possibilities
You may have set the routes wrong
The Facebook Redirect Url you specified might be wrong

Related

How to specify redirectUrl after logout for Ambassador OAuth2 Filter with Keycloak?

I'm using the Ambassador OAuth2 Filter to perform OAuth2 authorization against Keycloak.
For the logout I use the the RP-initiated logout as described in the Docs of Ambassador
The logout works fine. However I could not figure out how to provide the redirect url needed for Keycloak to redirect to the Login page after successfully logged out. As a result the user stays on the blank logout page of keycloak.
The RP-initiated logout looks as follows
const form = document.createElement('form');
form.method = 'post';
form.action = '/.ambassador/oauth2/logout?realm='+realm;
const xsrfInput = document.createElement('input');
xsrfInput.type = 'hidden';
xsrfInput.name = '_xsrf';
xsrfInput.value = getCookie("ambassador_xsrf."+realm);
form.appendChild(xsrfInput);
document.body.appendChild(form);
form.submit();
I expected that Ambassador provides a way to add the redirect url as a query param or something, but I couldn't find a solution.
Are there any suggestions or workarounds?
I found this in the Ambassador documentation that could be overlooked as I did several times:
Ambassador OAuth2 Settings
protectedOrigins: (You determine these, and must register them with your identity provider) Identifies hostnames that can appropriately set cookies for the application. Only the scheme (https://) and authority (example.com:1234) parts are used; the path part of the URL is ignored.
You will need to register each origin in protectedOrigins as an authorized callback endpoint with your identity provider. The URL will look like {{ORIGIN}}/.ambassador/oauth2/redirection-endpoint.
So it looks like ambassador hard codes the redirection-endpoint (redirect_uri) that you need add to your OAuth2 client in Keycloak.
I found a solution for that, is not the best solution but you will logout using a button.
async function logout() {
const data = new URLSearchParams("realm=keycloak-oauth2-filter.ambassador")
data.append('_xsrf', getCookie("ambassador_xsrf.keycloak-oauth2-filter.ambassador"));
fetch('/.ambassador/oauth2/logout', {
method: 'POST',
body: data
})
.then(function (response) {
if (response.ok) {
return response.text()
} else {
throw "err";
}
})
.then(function (text) {
console.log(text);
})
.catch(function (err) {
console.log(err);
});
}

Laravel Passport and Ionic2 Facebook-Login

I am developing a mobile app which should do API calls to an own laravel backend.
Frontend: Ionic 2 + Angular2
Backend: Laravel 5.3 + Laraval Passport + MySQL
At the user can log in with password grant (username + password).
Now I want to offer a login via Facebook.
I've implemented a Login with Facebook-button in the app. This works fine. I get the profile information from the Facebook API: id, email, name
Now this user (has no email + password combination from our server) should be able to make API calls to our Laravel server and should be linked to user in the users-table of the MySQL-database behind the laravel backend. Users which login with Facebook shouldn't need any username or password to login. Just Facebook.
I want to generate a new user in the database for each facebook user (simply with a column facebook_id). But how to give such users an access_token?
Accepting just the Facebook ID, match this (or create new) user in the database and create an access_token would be very unsecure because Facebook ID is public...
I must say I have same problem couple of weeks ago. Only difference I got was that I have both, ionic2 app and website. Both must support username/password login as social login (google, facebook).
So how did I did that (I will write for facebook, google is slightly different - better):
Prepare your facebook app to accept logins from mobile AND webpage. You will need facebook client_id and client_secret.
Install socialite package for laravel. And set it up to work with facebook ( in app/services.php set facebook ).
Now when you got this you can start coding. You said you already have it working on Ionic2 part. So that means you get token and other data from facebook for user.
What I did is I make request to my api and send this token and user_id. Then on my API side I check if token is valid, login user and issue passport token.
Ionic2 code:
Facebook.login(["public_profile"])
.then(response => {
// login success send response to api and get token (I have auth service class to do that)
this.auth.facebookLogin(response.authResponse).then(
...
);
}, error => {
this.showAlert( this.loginFailedTitle, this.loginFailedText );
});
Now Laravel part. I made SocialController.php and url (POST request) /api/social-login/facebook:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Model\SocialLogin;
use App\User;
use Illuminate\Http\Request;
use Socialite;
class SocialController extends Controller
{
public function facebook(Request $request) {
$user = Socialite::driver('facebook')->userFromToken( $request->input('accessToken'));
abort_if($user == null || $user->id != $request->input('userID'),400,'Invalid credentials');
// get existing user or create new (find by facebook_id or create new record)
$user = ....
return $this->issueToken($user);
}
private function issueToken(User $user) {
$userToken = $user->token() ?? $user->createToken('socialLogin');
return [
"token_type" => "Bearer",
"access_token" => $userToken->accessToken
];
}
}
Now this will return you passport token and you can make api request to protected routes.
About passport, email, username, ..... you will have to change database and make it nullable. And add facebook_id field.
And be sure to make requests over https, because your are sending token.
Hope it helps.
in addition to #Bostjan's answer adding my generalised implementation :
SocialAccount here is a laravel model where you'll provider and provider_user_id and local database user id. Below is the example of social_accounts table
And in SocialController :
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Http\Request;
use App\User;
use App\SocialAccount;
use Socialite;
class SocialController extends Controller
{
public function social(Request $request) {
$provider = $request->input('provider');
switch($provider){
case SocialAccount::SERVICE_FACEBOOK:
$social_user = Socialite::driver(SocialAccount::SERVICE_FACEBOOK)->fields([
'name',
'first_name',
'last_name',
'email'
]);
break;
case SocialAccount::SERVICE_GOOGLE:
$social_user = Socialite::driver(SocialAccount::SERVICE_GOOGLE)
->scopes(['profile','email']);
break;
default :
$social_user = null;
}
abort_if($social_user == null , 422,'Provider missing');
$social_user_details = $social_user->userFromToken($request->input('access_token'));
abort_if($social_user_details == null , 400,'Invalid credentials'); //|| $fb_user->id != $request->input('userID')
$account = SocialAccount::where("provider_user_id",$social_user_details->id)
->where("provider",$provider)
->with('user')->first();
if($account){
return $this->issueToken($account->user);
}
else {
// create new user and social login if user with social id not found.
$user = User::where("email",$social_user_details->getEmail())->first();
if(!$user){
// create new social login if user already exist.
$user = new User;
switch($provider){
case SocialAccount::SERVICE_FACEBOOK:
$user->first_name = $social_user_details->user['first_name'];
$user->last_name = $social_user_details->user['last_name'];
break;
case SocialAccount::SERVICE_GOOGLE:
$user->first_name = $social_user_details->user['name']['givenName'];
$user->last_name = $social_user_details->user['name']['familyName'];
break;
default :
}
$user->email = $social_user_details->getEmail();
$user->username = $social_user_details->getEmail();
$user->password = Hash::make('social');
$user->save();
}
$social_account = new SocialAccount;
$social_account->provider = $provider;
$social_account->provider_user_id = $social_user_details->id;
$user->social_accounts()->save($social_account);
return $this->issueToken($user);
}
}
private function issueToken(User $user) {
$userToken = $user->token() ?? $user->createToken('socialLogin');
return [
"token_type" => "Bearer",
"access_token" => $userToken->accessToken
];
}
}

ASP.NET Core Authorize Redirection to wrong URL

I am trying to run a web application with the following route mapped:
app.UseMvc(routes =>
{
routes.MapRoute(
"default",
"WoL/{controller=Account}/{action=Login}/{id?}");
});
If the user is not authenticated and tries to access a action having the AuthorizeAttribute, the user should be redirected to the default login URL (as seen above). But the user gets redirected to "/Account/Login" instead of "/WoL/Account/Login". How can I redirect the user to "/WoL/Account/Login", if the user is not authenticated? I have configured the following Cookie Authentication:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
LoginPath = new PathString("/WoL/Account/Login"),
AutomaticChallenge = true
});
The answer of #Dmitry is not working anymore in ASP.NET Core 3.1. Based on the documentation that you can find here, you have to add the following code to the ConfigureServices:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest)
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
This works for me (in Startup.ConfigureServices):
services.AddIdentity<User, UserRole>(options =>
{
options.Cookies.ApplicationCookie.LoginPath = new PathString("/Admin/Account/Login");
});
Try to add options.ForwardChallenge = "oidc"; to AddCookie options config

Cannot login through Facebook in Laravel 5.1

I am trying to login with facebook using Laravel 5.1.
I am following each steps mention in laravel documentation.
http://laravel.com/docs/5.1/authentication#social-authentication.
But, When i login through facebook then it will redirect to my normal login page.
In sort Session is store in facebook login.
This is a Code that is written by me.
Router.php
Route::get('auth/facebook','Auth\AuthController#redirectToProvider');
Route::get('auth/facebook/callback','Auth\AuthController#handleProviderCallback');
AuthController.php
public function redirectToProvider()
{
return Socialite::driver('facebook')
->scopes(['email', 'public_profile'])
->redirect();
}
public function handleProviderCallback()
{
$user = Socialite::driver('github')->user();
$user = Socialite::driver('github')->user();
// OAuth Two Providers
$token = $user->token;
// OAuth One Providers
$token = $user->token;
$tokenSecret = $user->tokenSecret;
// All Providers
$user->getId();
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();
}
Services.php
'facebook' => [
'client_id' => '1625567400000000',
'client_secret' => 'secret',
'redirect' => 'http://localhost:8000/',
],
When i type localhost/8000/auth/facebook it will redirect me to facebook and ask permission for public_profile, email etc.
And it will redirect back to localhost/auth/login.
And when i type localhost:8000/auth/facebook/callback in URL, it will through error like this;
ClientException in Middleware.php line 69:
Client error: 404
For your case, I guest you are using middleware to check if the user is already logged in. And this might the problem that you get redirect to localhost/auth/login
I hope following code could be useful to you
public function handleProviderCallback()
{
//retrieve user's information from facebook
$socUser = Socialite::driver('facebook')->user();
//check user already exists in db
$user = \App\User::where('email', $socUser->getEmail())->first();
if($user) {
// if exist, log user into your application
// and redirect to any path you want
\Auth::login($user);
return redirect()->route('user.index');
}
//if not exist, create new user,
// log user into your application
// and resirect to any path you want
$user = new \App\User ;
$user->email = $socUser->getEmail();
// ...
// ...
// ...
$user->save();
\Auth::login($user); // login user
return redirect()->route('user.index'); // redirect
}
note: I did not test my code but you should get some idea
for more information: http://laravel.com/docs/5.1/authentication
and as #mimo mention,
Your redirect url in the Services.php file has to be
localhost:8000/auth/facebook/callback
Your redirect url in the Services.php file has to be
localhost:8000/auth/facebook/callback

Zend Framework: How to redirect to original url after login?

I'm trying to implement a login system that will be smart enough to redirect a user back to the page they were on before they decided (or were forced to) go to the login page.
I know this seems like a similar question to this one, and this one, but they do not address both of my scenarios.
There are two scenarios here:
User specifically decides to go to login page:
<a href="<?php echo $this->url(array(
'controller'=>'auth',
'action'=>'login'), 'default', true); ?>">Log In</a>
User is redirected because they tried to access protected content:
if (!Zend_Auth::getInstance()->hasIdentity()) {
$this->_helper->redirector('login', 'auth');
}
How can I implement a solution for this without displaying the "redirect to" url in the address bar?
Save the destination URL in the session. I guess you have some kind of access pre-dispatch plug-in. Do it there. And then, in the login form handler, check for the destination URL in the session, and redirect to it after a successful authentication.
Sample code from my project:
class Your_Application_Plugin_Access extends Zend_Controller_Plugin_Abstract {
public function preDispatch(Zend_Controller_Request_Abstract $request) {
foreach (self::current_roles() as $role) {
if (
Zend_Registry::get('bootstrap')->siteacl->is_allowed(
$role,
new Site_Action_UriPath($request->getPathInfo())
)
) return; // Allowed
}
$this->not_allowed($request);
}
private function not_allowed(Zend_Controller_Request_Abstract $request) {
$destination_url = $request->getPathInfo();
// If the user is authenticted, but the page is denied for his role, show 403
// else,
// save $destination_url to session
// redirect to login page, with $destination_url saved:
$request
->setPathInfo('/login')
->setModuleName('default')
->setControllerName('login')
->setActionName('index')
->setDispatched(false);
}
...
}
Here, current_roles() always contains 'guest', which is unauthenticated user, for which Zend_Auth::hasIdentity() is false.