I'm making a Laravel 5.4 project where I want users to select a school (which they will be assigned to) before they register and the user is created.
My problem is that a google login is the main login method of the application and the user creation is handled in the LoginController. I'm using the Socialite package for the google login.
How do I pass the user and the data from the google callback to the register page?
This is my LoginController:
public function redirectToProvider()
{
return Socialite::driver('google')->redirect();
}
public function handleProviderCallback()
{
try
{
$user = Socialite::driver('google')->user();
}
catch (Exception $e)
{
return redirect('auth/google');
}
$authUser = $this->findOrCreateUser($user);
Auth::login($authUser, true);
return redirect('/home');
}
public function findOrCreateUser($googleUser)
{
$authUser = User::where('google_id', $googleUser->id)->first();
if ($authUser) {
return $authUser;
}
return User::create([
'name' => $googleUser->name,
'email' => $googleUser->email,
'google_id' => $googleUser->id,
'avatar' => $googleUser->avatar
]);
}
You can use flashed session.
Try this:
public function handleProviderCallback()
{
try
{
$user = Socialite::driver('google')->user();
}
catch (Exception $e)
{
return redirect('auth/google');
}
$authUser = User::where('google_id', $user->id)->first();
if($authUser) //if user is found
{
Auth::login($authUser, true);
return redirect('/home');
}
else //if user is not found, redirect to register page
{
return redirect('/register')->with('user', $user);
}
}
and in your register view
<input type='text' name='email' value='{{session("user")->email}}'>
Related
How can I create unique username using facebook register socialite laravel, I have the controller code below but I have no idea how it could be, I am new on laravel. Thanks in advance.
public function redirectToFacebook()
{
return Socialite::driver('facebook')->fields([
'name', 'email',
])->scopes([
'email'
])->redirect();
}
public function handleFacebookCallback()
{
try {
$user = Socialite::driver('facebook')->user();
$create['name'] = $user->getName();
$create['email'] = $user->getEmail();
$create['facebook_id'] = $user->getId();
$userModel = new User;
$createdUser = $userModel->addNew($create);
Auth::loginUsingId($createdUser->id);
return redirect()->route('/');
} catch (Exception $e) {
return redirect('/');
}
}
Concatinate the timestamp when the user loggs in like:
$time = Carbon::now()->timestamp;
$create['name'] = $user->getName().$time;
Also each time the user loggs in it will try to create a user so make sure you check first if user exists:
public function handleFacebookCallback()
{
try {
$user = Socialite::driver('facebook')->user();
$create['name'] = $user->getName();
$create['email'] = $user->getEmail();
$create['facebook_id'] = $user->getId();
$user = User::firstOrCreate($create);
Auth::loginUsingId($user->id);
return redirect()->route('/');
} catch (Exception $e) {
return redirect('/');
}
}
Use firstOrCreate() function to check if it exists if not then create it .
I know I'll lose the purpose if I store jwt token in my database but for some reason, i want to store it, how can I do that?
Controller
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Tymon\JWTAuth\JWTAuth;
class AuthController extends Controller
{
/**
* #var \Tymon\JWTAuth\JWTAuth
*/
protected $jwt;
public function __construct(JWTAuth $jwt)
{
$this->jwt = $jwt;
}
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email|max:255',
'password' => 'required',
]);
try {
if (! $token = $this->jwt->attempt($request->only('email', 'password'))) {
$create_token = User::where('user_id', $login->user_id)->update(['token' => $token]);
return response()->json(['user_not_found'], 404);
}
else {
$create_token = User::where('user_id', auth()->user()->user_id)->update(['token' => $token]);
}
} catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
return response()->json(['token_expired'], 500);
} catch (\Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
return response()->json(['token_invalid'], 500);
} catch (\Tymon\JWTAuth\Exceptions\JWTException $e) {
return response()->json(['token_absent' => $e->getMessage()], 500);
}
return response()->json(compact('token'));
}
public function logout(Request $request)
{
$this->jwt->invalidate($this->jwt->getToken());
return response()->json([
'message' => 'User logged off successfully!'
], 200);
}
}
I tried the method above but i got error saying Call to undefined function App\Http\Controllers\auth()
can anyone help me??
Not advised seeing that json web tokens are time sensitive but I did write something similar but for the use of redis. Looking at your code I would advise you create row for tokens and add it to the public $hidden = ['password','token']. When a user is created, you create and save a token to the database.
I'm using socialite to allow my users register and login with their social accounts such as, Facebook, Twitter, Google+ but it doesn't work, will give this error:
here is my LoginController
public function redirectToProvider()
{
return Socialite::driver('facebook')->redirect();
}
public function handleProviderCallback()
{
try{
$user = Socialite::driver('facebook')->user();
$user->token;
} catch (\Exception $e) {
return redirect()->intended('jobseekers/login');
}
$authUser = $this->findOrCreate($user);
Auth::login($authUser, true);
return redirect()->intended('jobseekers');
}
public function findOrCreate($facebookUser)
{
$authUser = User::where('id', $facebookUser->id)->first();
if($authUser)
{
Session::flash('success', 'Welcome, You are successfully Registered with your Facebook account');
return $authUser;
}
return User::create([
$user->id = $facebookUser->id,
$user->first_name = $facebookUser->name,
$user->last_name = $facebookUser->name,
$user->image = $facebookUser->avatar,
$user->email = $facebookUser->email,
]);
}
PS: code above will not register users and return errors but before that I used code below and it register users but will not give them password so they weren't be able to login that was the reason why I changed code below to code above:
public function redirectToProvider()
{
return Socialite::driver('facebook')->redirect();
}
public function handleProviderCallback()
{
$userSocial = Socialite::driver('facebook')->user();
$findUser = User::where('email', $userSocial->email)->first();
if ($findUser) {
Auth::login($findUser);
return redirect()->route('user.index');
}else{
$user = new User;
$user->id = $userSocial->id;
$user->first_name = $userSocial->name;
$user->last_name = $userSocial->name;
$user->image = $userSocial->avatar;
$user->email = $userSocial->email;
$user->save();
Auth::login($user);
Session::flash('success', 'Welcome, You are successfully Registered with your Facebook account');
return redirect()->route('user.index');
}
}
before code above I used
Update:
If i remove else{ ... } from my code user will register but same as my second code without password, so user is not able to login.
I solved my problem, here is final code:
public function handleProviderCallback()
{
try {
$user = Socialite::driver('facebook')->fields([
'first_name', 'last_name', 'email', 'gender'
])->scopes(['first_name', 'last_name'])->user();
} catch (Exception $e) {
return redirect()->route('user.index');
}
$authUser = $this->findOrCreateUser($user);
Auth::login($authUser, true);
return redirect()->route('jobseeker.profile');
}
/**
* Return user if exists; create and return if doesn't
*
* #param $facebookUser
* #return User
*/
private function findOrCreateUser($facebookUser)
{
$authUser = User::where('fb_id', $facebookUser->id)->first();
if ($authUser){
return $authUser;
}
return User::create([
'fb_id' => $facebookUser->id,
'first_name' => $facebookUser->user['first_name'],
'last_name' => $facebookUser->user['last_name'],
'username' => $facebookUser->user['last_name'],
'avatar' => $facebookUser->avatar,
'email' => $facebookUser->email,
'gender' => $facebookUser->user['gender'],
]);
}
I have a laravel application in this application i have following function for login user
public function login() {
try {
$inputs = Input::except('_token');
$validator = Validator::make($inputs, User::$login);
if ($validator->fails()) {
return Redirect::to('/')->with('message', 'Please Enter Valid Credentials');
} else {
$respones = \UserHelper::processLogin($inputs);
if ($respones) {
return Redirect::to('/dashboard')->with('success_message', 'Welcome to Tressly Admin Dashboard');
} else {
return Redirect::to('/')->with('message', 'Please Enter Valid Information ');
}
}
} catch (Exception $ex) {
return CommonHelper::AdminExceptions($ex);
}
}
Now as user logout and presses the back button , browser show previous page as it is present in cache. Now on this page as user tries to access any protected route application It shows following error
I want to redirect it to '/'( home route)as logged out user tries to acess any protect routes following error comes
Class App\Illuminate\Auth\Middleware\AdminAuthenticate does not exist
I have made a custom Authentication Middle , handle function of the middleware is
public function handle($request, Closure $next, $guard = null) {
if (Auth::check()) {
return $next($request);
}
return redirect('/');
}
I have also registered it in kernal.php in $routeMiddleware like
'authAdmin' => \Illuminate\Auth\Middleware\AdminAuthenticate::class,
and protected my route like
Route::group(['middleware' => 'authAdmin'], function () {
///routes
});
Any ideas ?
use
'authAdmin' => \App\Http\Middleware\AdminAuthenticate::class,
Instead of
'authAdmin' =>\Illuminate\Auth\Middleware\AdminAuthenticate::class,
I hope it it will work
Is there a reason you made a custom middleware class that does exactly the same thing as the already present 'auth' middleware?
RedirectifAuthenticated.php does this;
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
https://laravel.com/docs/5.3/authentication#protecting-routes
I am using Socialite for user logins and I would like to set a remember_token to remember the user when they login through Socialite.
Right now I have the following service to create or log the user in:
class SocialAccountService {
public function createOrGetUser(ProviderUser $providerUser) {
$account = SocialAccount::whereProvider('google')
->whereProviderUserId($providerUser->getId())
->first();
if ($account) {
return $account->user;
} else {
$account = new SocialAccount([
'provider_user_id' => $providerUser->getId(),
'provider' => 'google'
]);
$user = User::whereEmail($providerUser->getEmail())->first();
if (!$user) {
$user = User::create([
'email' => $providerUser->getEmail(),
'name' => $providerUser->getName()
]);
}
$account->user()->associate($user);
$account->save();
return $user;
}
}
}
It is called with the following controller:
class AuthController extends Controller {
public function logout() {
Auth::logout();
return redirect('/');
}
public function redirectToGoogle() {
return Socialite::driver('google')->redirect();
}
public function handleGoogleCallback(SocialAccountService $service) {
$user = $service->createOrGetUser(Socialite::driver('google')->user());
auth()->login($user);
return redirect('/');
}
}
The issue is that when the user comes back they are not remembered and automatically logged in. How can I do this with Socialite?
According to the documentation, passing true as the second argument of login() will set the remember token.
// Login and "remember" the given user... Auth::login($user, true);
The Auth facade and auth() helper function access the same object.