I am facing an issue when trying to login and register a user using Twitter. Google is working except for Twitter. I cant seem to figure it out.
Temporary identifier passed back by server does not match that of stored temporary credentials. Potential man-in-the-middle.
<?php
namespace App\Http\Controllers;
use Exception;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
class TwitterController extends Controller
{
protected $redirectTo = '/home';
public function redirectToProvider($provider)
{
return Socialite::driver($provider)->redirect();
}
public function handleProviderCallback($provider)
{
$user = Socialite::driver($provider)->user();
$authUser = $this->findOrCreateUser($user, $provider);
Auth::login($authUser, true);
return redirect($this->redirectTo);
}
public function findOrCreateUser($user, $provider)
{
$authUser = User::where('provider_id', $user->id)->first();
if ($authUser) {
return $authUser;
}
return User::create([
'name' => $user->getName(),
'username' => $user->getName(),
'email' => $user->getEmail(),
'provider' => $provider,
'provider_id' => $user->getId()
]);
}
}
Related
We are trying to setup the Facebook social connect on our Laravel application, but it seems like we have an issue on session creation.
Here is the code for the Controller :
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Laravel\Socialite\Facades\Socialite;
use App\Services\SocialAuthService;
class SocialAuthController extends Controller
{
public function redirect()
{
return Socialite::driver('facebook')->redirect();
}
public function callback(SocialAuthService $service)
{
$user = $service->createOrGetUser(Socialite::driver('facebook')->stateless()->user());
auth()->login($user);
return redirect()->intended('/');
}
}
And the code for the service :
<?php
namespace App\Services;
use Laravel\Socialite\Contracts\User as ProviderUser;
use Myproject\Users\User;
use Myproject\Users\SocialLogin;
class SocialAuthService
{
public function createOrGetUser(ProviderUser $providerUser)
{
$account = SocialLogin::where('provider', '=', 'facebook')
->where('provider_user_id', '=', $providerUser->getId())
->first();
if ($account) {
return $account->user;
}
$user = User::where('email', '=', $providerUser->email)->first();
if (!$user) {
$fullname = explode(' ', $providerUser->getName());
$user = User::create([
'email' => $providerUser->getEmail(),
'firstname' => $fullname[0],
'lastname' => $fullname[1],
'password' => md5(rand(1, 9999)),
]);
}
$account = new SocialLogin([
'provider_user_id' => $providerUser->getId(),
'provider' => 'facebook'
]);
$account->user()->associate($user);
$account->save();
return $user;
}
}
And finally the Model :
<?php
namespace Myproject\Users;
use Illuminate\Database\Eloquent\Model;
use Myproject\Users\User;
class SocialLogin extends Model
{
protected $table = 'social_logins';
protected $fillable = ['user_id', 'provider_user_id', 'provider'];
public function user()
{
return $this->belongsTo(User::class);
}
}
When we're trying to connect via Facebook, the information is correctly insert in Database, and the callback URL set on Facebook Developers correspond to what we have in our .env, so the redirection is correctly done but at the end we don't have any session created for the user.
I think the issue comes from cross-domain, here are the interesting parts of our .env file :
APP_URL=https://www.website.com
APP_DOMAIN=website.com
SESSION_DOMAIN=.website.com
CACHE_DRIVER=redis
SESSION_DRIVER=redis
SESSION_LIFETIME=120
FACEBOOK_REDIRECT=https://www.website.com/callback/facebook
GOOGLE_REDIRECT=https://www.website.com/auth/google/callback
And our routing on web.php :
Route::domain('{subdomain}.{domain}')->middleware('locale')->group(function () {
Route::get('/callback/facebook', 'Auth\SocialAuthController#callback');
Route::get('/redirect/facebook', 'Auth\SocialAuthController#redirect');
});
I really think the issue is located on routing or SESSION_DOMAIN, but we tried to :
delete the session domain
routing outside the middleware locale, in a middleware auth
It still doesn't affect the login.
So i'm trying to create an auth repository test using phpunit but i keep getting the error 'Call to a member function createToken() on null'. I think this is due to the RefreshDatabase trait but i'm installing passport on setup so i'm a bit lost. Any help is appreciated!
AuthRepository test
namespace Tests\Repository;
use App\Contracts\Auth;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AuthRepositoryTest extends TestCase
{
use RefreshDatabase;
protected $authRepository;
protected function setUp(): void
{
parent::setUp();
$this->artisan('passport:install');
$this->authRepository = app()->make(Auth::class);
}
/**
* Test Successful Login
*
* #return void
*/
public function testSuccessfulLogin(): void
{
$request = new \Illuminate\Http\Request();
$request->setMethod('POST');
$request->replace(['name' => 'test', 'email' => 'test', 'password' => 'testing']);
$this->authRepository->register($request);
$request = new \Illuminate\Http\Request();
$request->setMethod('POST');
$request->replace(['email' => 'test', 'password' => 'testing']);
$this->authRepository->login($request);
}
}
Test Case
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
protected function setUp(): void
{
parent::setup();
}
}
AuthRepository
<?php
namespace App\Repositories;
use App\Contracts\Auth;
use Illuminate\Support\Facades\Auth as Authenticate;
use App\User;
class AuthRepository implements Auth
{
public function Register($request)
{
$user = new User([
'name' => $request->input('name'),
'email' => $request->input('email'),
'password' => bcrypt($request->input('password'))
]);
$user->save();
return $user;
}
public function Login($request)
{
$credentials = $request->all();
if (!Authenticate::attempt($credentials))
return response()->json([
'message' => 'Unauthorized'
], 401);
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
$token->save();
return $tokenResult;
}
}
This is happened because the controller is trying to get the user data and create a token based on that.
In your case (happened to me too), there was a user variable which pointing the request to get the user credential while the user data is unknown because the user is not yet logged in.
To be clear, please take a look at your code within this line:
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
To fix that, change the line of $user = $request->user() to this:
$user = User::whereEmail($request->email)->first();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
I added registration, and I don't want to using laravels hash but mysql Hash (because I want existing users to still be able to connect).
So i do it step by step and for now I just try to register and then login without any hashing. The credentials are correct in my table but I get
"message":"The given data was invalid.","errors":{"email":["These credentials do not match our records."]}
I tried setting it in LoginController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
public function username()
{
return 'email';
}
public function password()
{
return 'email';
}
public function setPasswordAttribute($password){
$this->attributes['password'] = $password;
}
public function Login(Request $request)
{
if(Auth::attempt(['email' => $request->email, 'pwd' => $request->password, 'password' => $request->password])){
$user = Auth::user();
$username = $user->nom;
return response()->json([
'status' => 'success',
'user' => $username,
]);
} else {
return response()->json([
'status' => 'error',
'user' => 'Unauthorized Access'
]);
}
}
}
I guess I should overwrite another function, but can't find out which one.
Could you please give me some help?
Altough what you're trying to achieve is considered unsecure, to remove Laravel's hashing for password, you need to add this to your User model :
public function setPasswordAttribute($password){
$this->attributes['password'] = $password;
}
and not in your controller, and be sure to remove the brcypt() methods in your RegisterController
To add your MySQL own hashing methods, update your controller to insert a RAW query while creating a user upon registration
I want to log my users as soon as they register. here's my UserController's code (which works) :
<?php
namespace App\Http\Controllers;
use App\Http\Requests\Login;
use App\Http\Requests\Register;
use App\User;
class UserController extends Controller
{
public function register(Register $request)
{
User::create($request->all());
$loginRequest = new Login();
$loginRequest['email'] = $request->get('email');
$loginRequest['password'] = $request->get('password');
return $this->login($loginRequest);
}
public function login(Login $request)
{
return 'ok';
}
}
I feel I'm doing something ugly with my $loginRequest. Is there a neater way to do the same ? Aka transform my Register request into a Login request ?
You are simply trying to logged in user into his account after the registration so use Auth::login($user)
class UserController extends Controller
{
public function register(Register $request)
{
$user = User::create($request->all());
\Auth::login($user);
}
}
As soon as user register you can use this snippet of code to attempt a login
if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
return Redirect::route('dashboard');
}
So the code should be
User::create($request->all());
$loginRequest = new Login();
$loginRequest['email'] = $request->get('email');
$loginRequest['password'] = $request->get('password');
if (Auth::attempt(['email' => $request->get('email'),
'password' => $request->get('password')])) {
return Redirect::route('dashboard');
}
Undefined property: Illuminate\Validation\Validator::$errors in laravel
here is my controller file how to solve it i think here problem is any namespace where is it i do not know please guide me
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Route;
use Input;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Http\Request;
use App\models\Designation;
use Validator;
use Illuminate\Support\Facades\Response;
class Cdesigination extends Controller
{
public $flight;
public function __construct(){
$this->flight = new Designation;
}
public function index()
{
return view('designation');
}
public function techer(Request $request) {
$Validator =Validator::make(array(
'name'=>Input::get('name'),
'detail'=>Input::get('detail')
),array(
'name' => 'required',
'detail' => 'required'
));
if ($Validator->fails()) {
return Response::json([
'success'=>false,
'error' =>$Validator->errors->toArray()
]);
}
else{
$this->flight->name = $request->name;
$this->flight->detail = $request->detail;
$this->flight->save();
return Response::json([
'success'=>true]);
}
}
$Validator->errors()->toArray()
Errors() is function, so the braces are important