I have asked this question already but still I didn't get an answer.
How to login using Github, Facebook, Gmail and Twitter in Laravel 5.1?
auth not working
I am able to store data from gmail, github in the database.
Controller
if (Auth::attempt(['email' => $email, 'password' => $user_id]))
{
return redirect()->intended('user/UserDashboard');
}
else
{
//here i am going to insert if user not logged in already
return redirect()->intended('user/UserDashboard');
}
My problem is if I echo any data instead of return redirect()->intended('user/UserDashboard'); then it displays. If I add redirect then it doesn't work.
I'm not entirely sure how it works when using google for oAuth, but I assume your desired flow is:
User returns from google.
Check if user already exists, otherwise create new user record.
Log user in.
Redirect to dashboard.
Assuming the above your methods would look something like this.
Controller
public function google()
{
// Redirect user to google for authentication
return Socialite::driver('google')->redirect();
// In Laravel 5.0 this would be
// return Socialize::with('google')->redirect();
}
public function googleCallback()
{
// Return from google with user object
$googleUser = Socialite::driver('google')->user();
// In Laravel 5.0 the above would be
// $user = Socialize::with('google')->user();
// If user exists, retrieve the first() record,
// otherwise create a new record
$user = User::firstOrCreate([
'user_id' => $googleUser->id,
'name' => $googleUser->name,
'password' => $googleUser->id,
'email' => $googleUser->email,
'avatar' => $googleUser->avatar
]);
// Login the user
Auth::login($user, true);
// Redirect to the dashboard
return Redirect::intended('user/UserDashboard');
}
Related
I'm developing a webpage with Laravel 8 and I have issues with fetching a patron details by id from Patreon API. Here is my use case.
I’ve added "Login with Patreon" option to my webpage, and it works well. When someone login with Patreon successfully, I store her/his Patreon id and set remember token to login the member automatically when she/he visits my page next time.
The first login process is fine. The problem occurs when my Patron visits my page next time. Because I want to check whether I received any payment before I let she/he see all content. That’s why I need to get my patron details from a middleware. To do that I tried:
fetch_user() returns my account details instead of logged-in user.
fetch_user() with the access token that returns from Patreon when
someone login, returns unauthorized.
fetch_member_details() doesn’t work with the id I passed, which is an
integer like 5484646 because it requires a very long string like
55153fds-f45fd5sfs-fds42ds, I don't know what it's.
fetch_page_of_members_from_campaign() and fetch_member_details()
together to get the proper ID, but it takes ages to get data, which
is unacceptable.
So, how can it be done?
https://further-reading.net/2020/06/getting-names-of-your-patreon-patrons-by-tier/
This might be useful. I believe, there is not a direct single API for this, but you can -
First fetch all campaigns/tiers data
And then fetch patrons for each campaign/tier
I like to answer my question for those who need some help.
First of all, I use the official PHP package by Patreon
I've created a middleware to check if the user should be authorized again. In order to prevent the same process every single time, I set timeout to users table and check if it still has time to expire. If it does, no need to do anything. Of course, this is my use case, but without that explanation, some parts of the code can be nonsense to you.
// App\Http\Middleware\AuthenticateMember.php
public function handle(Request $request, Closure $next)
{
if (!Auth::check()) {
return $next($request);
}
if (Carbon::parse(Auth::user()->timeout)->isFuture()) {
return $next($request);
}
$this->refreshCredentials();
return $next($request);
}
If "timeout" isn't in the future, refreshCredentials method will be called. This is a method, which will trigger binding AuthGatewayContract to the service container.
// App\Trait\Users.php
public function refreshCredentials()
{
$gateway = App::make('App\Services\AuthGatewaysContract');
$gateway->ensureUserStillAuthenticated();
}
public function handleUserRecord($user)
{
return User::updateOrCreate([
'email' => $user['email']
], $user);
}
public function attemptToLogin($user, $remember = true)
{
Auth::login($user, $remember);
event(new Registered($user));
}
This is how the binding works:
// App\Providers\AppServiceProvider.php
public function register()
{
$this->app->singleton(AuthGatewaysContract::class, function () {
$routeParts = explode('/', url()->current());
$gateway = array_pop($routeParts); // this is how I know which "Login with ..." button is clicked.
$isGateway = Gateway::where('name', $gateway)->first();
$gateway = $isGateway ? ucfirst($gateway) : ucfirst(Auth::user()->gateway->name);
$class = "\App\Services\AuthGateways\\$gateway";
return new $class();
});
}
So Patreon.php is active gateway now, and ensureUserStillAuthenticated can be called:
// App\Services\AuthGateways\Patreon.php
public function ensureUserStillAuthenticated()
{
$this->authenticate([
'access_token' => Auth::user()->access_token,
'refresh_token' => Auth::user()->refresh_token,
]);
}
private function authenticate($tokens)
{
$patron = $this->fetchUserFromGateway($tokens);
$user = $this->handleResponseData($patron, $tokens);
$user = $this->handleUserRecord($user);
return $this->attemptToLogin($user);
}
private function fetchUserFromGateway($tokens)
{
// This is the only function that communicate with Patreon-php package.
$api_client = new API($tokens['access_token']);
return $api_client->fetch_user();
}
private function handleResponseData($data, $tokens)
{
return [
'name' => $data['data']['attributes']['full_name'],
'email' => $data['data']['attributes']['email'],
'password' => Hash::make(Str::random(24)),
'role_id' => $this->assignRoleId($data),
'payment_id' => Payment::where('name', 'patreon')->first()->id,
'gateway_id' => Gateway::where('name', 'patreon')->first()->id,
'access_token' => $tokens['access_token'],
'refresh_token' => $tokens['refresh_token'],
'timeout' => Carbon::today()->addMonth()->toDateString()
];
}
I am trying to add social authentication to a Laravel 5.8 API project using socialite.
When trying to handle a social provide callback, the ArgumentCountError is thrown here
Too few arguments to function App\Http\Controllers\SocialAuthController::handleProviderCallback(), 0 passed and exactly 1 expected
The error is referring to the very first line of this code block
public function handleProviderCallback($provider)
{
// retrieve social user info
$socialUser = Socialite::driver($provider)->stateless()->user();
// check if social user provider record is stored
$userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();
if ($userSocialAccount) {
// retrieve the user from users store
$user = User::find($userSocialAccount->user_id);
// assign access token to user
$token = $user->createToken('Pramopro')->accessToken;
// return access token & user data
return response()->json([
'token' => $token,
'user' => (new UserResource($user))
]);
} else {
// store the new user record
$user = User::create([
'name' => $socialUser->name,
'username' => $socialUser->email,
'email_verified_at' => now()
]);
...
// assign passport token to user
$token = $user->createToken('******')->accessToken;
// return response
return response()->json(['token' => $token]);
}
}
Below is how I have set up other code. Frist in env I added
GOOGLE_CLIENT_ID=******
GOOGLE_CLIENT_SECRET=*******
GOOGLE_CALLBACK_URL=https://staging.appdomain.com/api/v1/user
Then modified web.php
Auth::routes(['verify' => true]);
Route::get('/auth/{provider}', 'SocialAuthController#redirectToProvider');
Route::get('/auth/{provider}/callback', 'SocialAuthController#handleProviderCallback');
Lastly in the google app, I added the uri path where users will be redirected to after successful authentication
https://staging.appdomain.com/api/v1/user
How do I fix this?
The callback uri that user should be redirected to after successful authentication was apparently not being cached. So running php artisan route:cache fixed it.
I am using socialite to integrate the login with Facebook function. Here is my code:
public function handleProviderCallback()
{
try {
$socialUser = Socialite::driver('facebook')->user();
} catch (\Exception $e) {
return redirect('/dashboard');
}
/*section1 : i check if the user exists in the db, and if no then
I save this user in the db */
$user = User::where('facebook_id', $socialUser->getId())->first();
if (!$user) {
User::create([
'facebook_id' => $socialUser->getId(),
'name' => $socialUser->getName(),
'email' => $socialUser->getEmail(),
]);
Auth::loginUsingId($socialUser->id);
return redirect()->intended('/dashboard');
}
/* end of section one */
else{
if(Auth::loginUsingId($user->id)){
return redirect()->intended('/dashboard');
}
}
}
The problem is: I login with a new user, the data is added to the database and I am redirected to the dashboard, but I am not logged in. After I try logging in again (when the user already exists in the database) I am successfully logged in. Why? Thanks!
The issue is with following line. You have to pass the user id in the database, not the Facebook id.
Auth::loginUsingId($socialUser->id);
Update as following
$newUser = User::create(...);
Auth::loginUsingId($newUser->id);
After reading: http://laravel.com/docs/5.0/authentication I was able to retrieve the user details from the OAuth provider (Facebook) using Socialite:
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();
But I couldn't find any further documentation on how to save the user in the database or log the user in.
I want to do the equivalent to:
Auth::attempt(['email' => $email, 'password' => $password])
But for the details retrieved via Socialite (I don't have a password)
Can you please show me an example on using "Auth" with user data retrieved via Socialite?
Add to "users" table new column: facebook_user_id. Every time when user tries to login through Facebook, Facebook will return the same user id.
public function handleProviderCallback($provider)
{
$socialize_user = Socialize::with($provider)->user();
$facebook_user_id = $socialize_user->getId(); // unique facebook user id
$user = User::where('facebook_user_id', $facebook_user_id)->first();
// register (if no user)
if (!$user) {
$user = new User;
$user->facebook_id = $facebook_user_id;
$user->save();
}
// login
Auth::loginUsingId($user->id);
return redirect('/');
}
How Laravel Socialite works?
public function redirectToProvider()
{
// 1. with this method you redirect user to facebook, twitter... to get permission to use user data
return Socialize::with('github')->redirect();
}
public function handleProviderCallback()
{
// 2. facebook, twitter... redirects user here, where you write code to log in user
$user = Socialize::with('github')->user();
}
I am trying to create an authentication for facebook users. Right now I check to see if a fb user id exist in my database, if it does then it authenicates, if not, then it data mines the users facebook info and creates a user and then authenicates. It works successfully, the problem is, if I use something like $this->Auth->user('id'); the values return back null. I am curious on what I maybe doing wrong. below is my code
public function fb_authenticate($data) {
$this->Auth->fields = array('username' => 'fbid', 'password' => 'fbpassword');
$this->loadModel('User');
$user_record = $this->User->find('first', array(
'conditions' => array('fbid' => $data['user_id'])
));
if(empty($user_record)) {
$fbu = $this->Facebook->getUserInfo($data['user_id']);
$user_record = array(
'User'=>array(
'username'=>$fbu->username,
'fbid'=>$data['user_id'],
'oauth_token'=>$data['oauth_token'],
'access_token'=>$data['access_token'],
'firstname'=>$fbu->first_name,
'lastname'=>$fbu->last_name,
'fbpassword'=>$this->Auth->password($data['user_id']),
'role'=>'user'
));
$this->User->create();
$this->User->save($user_record,null);
}
if (!$this->Auth->login($user_record)) {
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
It authenicates and lets the user in, but it does not store the users info in the Auth component session. what could be the problem ??
if I debug debug($this->Auth->user()) I can see the data but if I pull a field individually debug($this->Auth->user('id')); it returns null.
Change $this->Auth->login($user_record)
to $this->Auth->login($user_record['User']).