I'm currently adding Socialite to my website to allow users to log in from Facebook.
public function redirectToProviderFacebook() {
return Socialite::driver('facebook')->redirect();
}
public function handleProviderCallbackFacebook() {
$userSocial = Socialite::driver('facebook')->user();
$email = $userSocial->getEmail();
if (User::where('email', $email)->count() > 0) {
// log them in
Auth::login(User::where('email', $email)->first());
return redirect()->route('home')->with('info', "You are now signed in.");
} else {
// register an account and log them in
}
}
During normal user registration, I ask for three things: username, email and password. The username and email are things you cannot change on my site, ever, as their usernames are bound to many things.
The problem with logging in with Facebook is that I have to register new users in the callback function. Therefore, I can't ask them for what they want their usernames to be.
Is there a way I could perhaps prompt the user for their preferred username? Then do the redirect like this:
return Socialite::driver('facebook')->with('username', $request->username)->redirect();
Then retrieve that data to use it for auth registration in the callback function?
For some reason, Optional Parameters didn't work for me, so i ended up by using session to pass variables from redirect method to the callback method. it's not the best way to do it, but it does the trick.
public function redirectToFacebookProvider()
{
// save anything you will need later, for example an url to come back to
Session::put('url.intended', URL::previous());
return Socialite::driver('facebook')->redirect();
}
public function handleFacebookProviderCallback()
{
// handling....
$url = Session::get('url.intended', url('/'));
Session::forget('url.intended');
return redirect($url);
}
Obtained this answer from https://laracasts.com/discuss/channels/laravel/socialite-return-parameters-in-callback?page=0
And from Sending additional parameters to callback uri in socialite package for laravel
i am not sure about facebook, but for github its working fine. Try this:
public function socialLogin($loginFrom){
return Socialite::driver('github') >redirectUrl('http://your-domain.com/callback?data=123')->redirect();
}
on github app you need to put only: http://your-domain.com/callback
Related
In my Symfony project I'm using UserInterface in my User entity to handle authentication. I also use EquatableInterface to check if user's email is changed while he's logged in.
public function isEqualTo(UserInterface $user)
{
if (!$user instanceof Account) {
return false;
}
if ($this->email !== $user->getEmail()) {
return false;
}
return true;
}
All works as expected, but when I change user's email in DB I'm not logged out, just not authenticated as you can see in the following screenshot.
So I would know how can I check in a controller if user is authenticated? And how can I force user to log out when isEqualTo returns false?
I found the solution and I want to share it if someone else have the same problem.
To check if user is authenticated, we need TokenInterface which is implemented by TokenStorage. Then we just need to call isAuthenticated() method.
$tokenInterface = $this->get('security.token_storage')->getToken();
$isAuthenticated = $tokenInterface->isAuthenticated()
Fast Method: see method getUser in Symfony\Bundle\FrameworkBundle\Controller at link. If you need this behavior somewhere in the service, then use the security.token_storage service as a dependency.
Try way method (symfony-like): you need use Symfony Security Voters
I'm having some trouble wrapping my head around whether or not things are working as intended.
I've got a simple implementation of cakephp3, cake-auth0 (https://github.com/jsoftb/auth0) and I am using an auth0 login form.
This flow works just fine.
example.com/users/login -> form -> my-domain.auth0.com -> example.com/users/login?code=secret
$auth_code = $this->request->query('code', null);
if(!is_null($auth_code)) {
$user = $this->Auth->identify();
if($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl()); // example.com/
}
}
Logging a user out is where I'm having issues.
example.com/users/logout -> auth0-domain (kill cookie) -> example.com
public function logout() {
return $this->redirect($this->Auth->logout());
// $this->redirect('http://auth0.domain?returnTo=http://example.com/');
}
public function beforeFilter(Event $event) {
parent::beforeFilter($event);
$this->Auth->allow('logout'); // Appears to do nothing
}
This successfully logs me in and out of auth0 just fine.
I stay logged into cake however and it is driving me a bit batty.
My login page with some session user output shows me as logged in and I can access the page example.com/users. I cannot view it while not yet logged in.
I haven't created any database stuff to go with users yet if that helps.
Short of going brutal and nuking all sessions/cookies using just php, anyone else have any ideas?
Update: Dug a lot through code. Cake's vanilla Authcomponent::logout doesn't do much of anything. I managed to get something that will work for me by manually killing a session of some sort.
I'll leave this up because I know some guru will come along at some point.
I was able to achieve logging out (of cake) like this:
public function logout() {
$url = $this->Auth->logout();
$this->request->session()->destroy();
return $this->redirect($url);
}
Call AuthComponent's logout function and save the response url string.
Destroy the request session because logout didn't do it.
Redirect.
I have this function for socialite login:
public function login()
{
return Socialite::driver('facebook')->redirect();
}
public function callback()
{
return redirect('/')->with('message','Logged in!!');
}
The callback function only redirects to homepage where there is a form to add, a song:
public function add(Request $request)
{
$newSong = new Song();
$newSong->name=$request->song;
$newSong->added_by=Socialite::driver('facebook')->user()->name;
$nrwSong->save();
}
But when i try to add added_by field in database from this social authentication, it gives
InvalidStateException in AbstractProvider.php
What am i doing wrong here? I can see user details if i dd(Socialite::driver('facebook')->user()); in callback function.
You should be getting the users information in the callback (Which is the only place in the documentation you see that call being done). Facebook is sending the user back to that callback with data (inputs).
The state part you are running into is part of these inputs and also saved in the session. When you call Socialite::driver('facebook')->user(), it is looking in the current request for the state input, which doesn't exist because you are now on a different request because you redirected the user.
My website requires a users account to be activated by an email link that is sent out to them before they can actually log in however the guard() attempt() method seems to sign the user in as long as there is a match. How would I just check without logging in so I can validate the user > verify their account is active > start a user session? The current code is as follows
if ($this->guard()->attempt($credentials, $request->has('remember'))) {
// Return response if user match found
return $this->checkAccountActive($credentials);
}
Are you using AuthController?
In case you do you can adjust the getCredentials() method to meet your business requirements, for example if you need the email confirmed and the status active you could do something like the following:
protected function getCredentials($request)
{
return array_merge($request->only(['email', 'password']), ['active' => 1]);
}
I understand that the auth functions allows a user to login etc, but I wanted a confirmation on what exactly was happening in the background.
My guess is that it's just a cookie that holds the login details, correct?
Or is it only storing the remember_token and then automatically comparing that with what is stored in the users table?
So if I wanted to create an account edit page. Would I have to do anything like comparing the auth id with the users table id that the e-mail matches up with? Or is it handling all that automatically?
Laravel Auth is nothing but its class where already all authentication methods or functions are written in laravel out of box.so you need not required to write all that function which is relating to user login.for example to check user we simply use
Auth::check();
but in laravel auth class they written like this
public function check()
{
return !is_null($this->user());
}
in the same way for login attempt we are passing parameter to attempt method .Here also laravel built in function is there
public function attempt(array $credentials = [], $remember = false, $login = true)
{
$this->fireAttemptEvent($credentials, $remember, $login);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// If an implementation of UserInterface was returned, we'll ask the provider
// to validate the user against the given credentials, and if they are in
// fact valid we'll log the users into the application and return true.
if ($this->hasValidCredentials($user, $credentials)) {
if ($login) {
$this->login($user, $remember);
}
return true;
}
return false;
}
Here you are passing all credentials in array and remember password and all