Logout doesn't logout in laravel socialite - laravel-socialite

I am unable to logout the google user in my application,when i logout it was redirecting login page saying it is successfully logged out but when i click login with google button it is redirecting to previous logged in user i.e., it is not logged out
my controller code:
class LoginController extends Controller {
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct() {
$this->middleware('guest')->except('logout','getLogout');
}
/**
* Redirect the user to the GitHub authentication page.
*
* #return \Illuminate\Http\Response
*/
public function redirectToProvider() {
return Socialite::driver('google')->redirect();
}
/**
* Obtain the user information from GitHub.
*
* #return \Illuminate\Http\Response
*/
public function handleProviderCallback() {
$user = Socialite::driver('google')->stateless()->user();
if($user) {
$authUser = $this->findOrCreateUser($user);
Auth::login($authUser, true);
}
return view ( 'home' )->withDetails ( $user )->withService ( 'google' );
// $user->token;
}
/**
* Return user if exists; create and return if doesn't
*
* #param $githubUser
* #return User
*/
private function findOrCreateUser($googleUser) {
if ($authUser = User::where('email', $googleUser->email)->first()) {
return $authUser;
}
return User::create([
'name' => $googleUser->name,
'email' => $googleUser->email,
]);
}}
I have followed the laravel documentation steps for this social login but i am unable to logout from my application..can anyone explain why this is going to happen??

Well, finally i found solution to my question.Actually, there is nothing to worry about it.Logout code is working pretty good.Google account ask for permission for first time login after getting grant access it won't ask for permission it directly continues to login.If we logout the google account then it will ask for permission otherwise it won't

Related

Android samples files for Azure B2C require configuration file information to be replicated in B2CConfiguration class as well

I was implementing Azure AD B2C in Multiuser mode and was reading the sample files. Why is there a configuration class which states:
"If you'd like to use your own app registration, you will also need to update B2CConfiguration.java to match with your configuration json file."
Doesn't that seem to defeat the purpose of having a configuration file? Shouldn't the values be accessible through the module somehow as long as the configuration file is
This code shows the calling of the json configuration file:
// Creates a PublicClientApplication object with res/raw/auth_config_single_account.json
PublicClientApplication.createMultipleAccountPublicClientApplication(getContext(),
R.raw.auth_config_b2c,
new IPublicClientApplication.IMultipleAccountApplicationCreatedListener() {
#Override
public void onCreated(IMultipleAccountPublicClientApplication application) {
b2cApp = application;
loadAccounts();
}
#Override
public void onError(MsalException exception) {
displayError(exception);
removeAccountButton.setEnabled(false);
runUserFlowButton.setEnabled(false);
acquireTokenSilentButton.setEnabled(false);
}
});
And the B2CConfiguraiton shows:
/**
* Name of your B2C tenant hostname.
*/
final static String azureAdB2CHostName = "fabrikamb2c.b2clogin.com";
/**
* Name of your B2C tenant.
*/
final static String tenantName = "fabrikamb2c.onmicrosoft.com";
/**
* Returns an authority for the given policy name.
*
* #param policyName name of a B2C policy.
*/
public static String getAuthorityFromPolicyName(final String policyName) {
return "https://" + azureAdB2CHostName + "/tfp/" + tenantName + "/" + policyName + "/";
}
/**
* Returns an array of scopes you wish to acquire as part of the returned token result.
* These scopes must be added in your B2C application page.
*/
public static List<String> getScopes() {
return Arrays.asList(
"https://fabrikamb2c.onmicrosoft.com/helloapi/demo.read");
}
All of these values are in the configuration file, except for scopes.
Is there another option here so I don't need to hard code configuration information?
The configuration details (like tenentid, policy name)can't be rendered dynamically.
In the B2CConfiguration.java file if you see the comments section it was mentioned as The value in this class has to map with the json configuration file (auth_config_b2c.json).

Symfony4. Force change password. Redirect to change-password site

I build login logic myself and i don't want use FosUserBundle.
I check Entity User date of last change password and if is more than 30 days i want that user will not fully authenticated only redirect to sites that they will must change password.
I try to use SecurityListener and onSecurityInteractiveLogin method.
Checking date works, but user is authenticated and redirect to sites what i configured in case after correct login (not to route change-password).
class SecurityListener
{
private $tokenStorage;
private $em;
private $session;
private $urlGenerator;
public function __construct(TokenStorage $tokenStorage, EntityManager $doctrine, Session $session, UrlGeneratorInterface $urlGenerator)
{
$this->tokenStorage = $tokenStorage;
$this->em = $doctrine;
$this->session = $session;
$this->urlGenerator = $urlGenerator;
}
/**
* #param InteractiveLoginEvent $event
* #return RedirectResponse
*/
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
$lastPasswordAt = $this->tokenStorage->getToken()->getUser()->getlastPasswordAt();
$data = new \DateTime("now");
$data->modify('-30 days');
if ($lastPasswordAt < $data) {
$this->session->invalidate();
return $this->urlGenerator->generate('app_change_password');
}
}
}
Please give me some hints how to handle this issue.

How to render twig templates into a service. Is it Best practice?

I have the following Symfony 3 controller:
public function register(Request $request)
{
$username=$request->get('username');
$password=$request->get('password');
$email=$request->get('email');
$captchaResponse=$request->get('g-recaptcha-response');
$session =$request->getSession();
$res1 = new Response();
$response_data=array('status'=>0);
if($session->get('captcha')===$captchaResponse)
{
$en = $this->container->get('user_model');
$data=$en->register($username,$password,$email);
$res1->headers->set('Content-Type','text/json');
if($data['status']===false)
{
$response_data['data']="An Internal error Happened";
error_log($data['data']);
}
else if($data['status']===-1)
{
$response_data['data']=$data['data'];
}
else
{
$response_data['status']=1;
$response_data['data']="Please check your mail to confirm your registration.";
/*Send Email*/
$message = \Swift_Message::newInstance()
->setSubject('Please confirm your registration')
->setFrom('symphotest#openmailbox.org')
->setTo($email)
->setBody($this->renderView('emails/confirm.html.twig',array('token'=>$data['data'])))
->addPart(
$this->renderView('emails/registration.txt.twig',array('token'=>$data['data'])),
'text/plain'
);
$this->get('mailer')->send($message);
}
}
else
{
$response_data['data']="You have not given a correct captcha";
}
$res1->setContent(json_encode($response_data));
$session->set('captcha',uniqid());//Generate gibberish in order not to reuse the very same captcha again
return $res1;
}
And I have made the following service:
namespace AppBundle\Models;
use Doctrine\ORM\EntityManager;
use AppBundle\Util\ModelStatus;
use AppBundle\Exceptions\InvalidArgumentException;
use \SwiftMessage;
class UserModel
{
/** #var EntityManager */
private $em;
/** #var \Swift_Mailer */
private $mailer;
/** #var \Twig_Environment */
private $twig;
/**
*
* #param EntityManager $em
* #param \Swift_Mailer $mailer
* #param \Twig_Environment $twig
*/
public function construct(EntityManager $em, \Swift_Mailer $mailer,\Twig_Environment $twig)
{
$this->em=$em;
$this->$mailer=$mailer;
}
/**
* Performs the actions needed for Registration
*
* #param unknown $username
* #param unknown $password
* #param unknown $email
* #param \Swift_Message $registrationMessage
*
* #return ModelStatus
*/
public function register($username,$password,$email)
{
$modelStatus=new ModelStatus();
try
{
/** #var \AppBundle\Entity\UserRepository */
$repository=$this->em->getRepository('AppBundle::Users');
$token=$repository->register($username,$password,$email);
$modelStatus->setData($token);
$modelStatus->setStatus(ModelStatus::STATUS_SUCCESS);
$this->mailer->send($registrationMessage);
$message = Swift_Message::newInstance()
->setSubject('Please confirm your registration')
->setFrom('symphotest#openmailbox.org')
->setTo($email)
->setBody($this->twig->//->renderView('emails/confirm.html.twig',array('token'=>$data['data'])))
->addPart(
$this->renderView('emails/registration.txt.twig',array('token'=>$data['data'])),
'text/plain'
);
$this->get('mailer')->send($message);
}
catch(InvalidArgumentException $arg)
{
$modelStatus->setStatus(ModelStatus::STATUS_FAILURE);
$modelStatus->setMessage($arg->getMessage());
}
catch (\Exception $e)
{
$modelStatus->setStatus(ModelStatus::STATUS_FAILURE);
$modelStatus->setMessage($e->getMessage());
}
return $modelStatus;
}
}
And I am refactoring the following section:
$message = \Swift_Message::newInstance()
->setSubject('Please confirm your registration')
->setFrom('symphotest#openmailbox.org')
->setTo($email)
->setBody($this->renderView('emails/confirm.html.twig',array('token'=>$data['data'])))
->addPart(
$this->renderView('emails/registration.txt.twig',array('token'=>$data['data'])),
'text/plain'
);
$this->get('mailer')->send($message);
Into the Model method register.
But As you can see I render some twig templates and I do know the best Option on how to do it. So far I thought the following options:
To render the templates as string and pass them to the the register method, create and send the email there.
Load the twig rendering service into the model and the render into the model. If not exists create one.
In the second bullet I may need to load the Twig rendering engine into a service. How can I do that?
In the end having the constructor like this:
public function __construct(EntityManager $em, \Swift_Mailer $mailer,\Twig_Environment $twig)
{
$this->em=$em;
$this->mailer=$mailer;
$this->twig=$twig;
}
And loading the service like this:
user_model:
class: AppBundle\Models\UserModel
arguments: ['#doctrine.orm.entity_manager','#mailer','#twig']
Seems that solved the problem.

Automatically merge session user in Symfony2

I have written my own User-class extending Symfony's UserInterface and EquatableInterface which gets authenticated nice on logins and is correctly retrievable using $this->getUser(); in a controller.
Now, my question is, if it is possible to write something (dunno, a listener for example) that can automatically merge the user coming from the open session (so the one you retrieve with $user = $this->getUser();), so I dont have to call stuff like:
/**
* #Route("/url/to/route")
*/
public function myAction()
{
$user = $this->getUser();
$mergedUser = $this->getDoctrine()->getManager()->merge($user);
return array('user' => $mergedUser);
}
But instead:
/**
* #Route("/url/to/route")
*/
public function myAction()
{
/* User gets merged automatically! */
$mergedUser = $this->getUser();
return array('user' => $mergedUser);
}

GWT cross-domain rpc

I need to call a GWT application service from javascript which is running on different domain.
How could this be done? How do I point from my applicaton to the javascript url?
Thank you.
The idea behind a cross domain request is the your java script creats a script tag which loads a generated java script from the forgein url. When loaded the generated java script is evaluated and calls a callback function you created.
The following code ist not testet and shows the idea:
public class CrossSiteDomainRequest {
/** Counter to create unique ids for callback function. */
private static int idCounter = 0;
/** Url to load the javascript from. */
private String url;
/**
* Creates a new loader with the given <code>url</code>.
* #param url to load the java script from {#link #url}.
*/
public CrossSiteDomainRequest(String url) {
this.url = url;
}
/**
* Uses the {#link #url} to load the data from another url.
*/
public void load() {
String callbackId = "callbackId" + idCounter++;
String prepend = url.indexOf("?") != -1 ? "&" : "?";
String u = url + prepend + "callback=" + callbackId// Add more Parameters
createCallback(this, transId);
Element script = DOM.createElement("script");
script.setAttribute("src", u);
script.setAttribute("id", callbackId);
script.setAttribute("type", "text/javascript");
script.setAttribute("language", "JavaScript");
getHead().appendChild(script);
}
/**
* Destroys the callback with the given <code>id</code>.
* #param id of the script tag and native javascript callback function which should be destroyed.
*/
protected void destroyCallbackmethod(String id) {
getHead().removeChild(DOM.getElementById(id));
removeCallback(id);
}
/**
* This method is invoked by the callback to handel the loaded data.
* #param callbackId DOM-Id of the callback whick invoked this method.
* #param jso Object that encapsultes the loaded data.
*/
#SuppressWarnings("unchecked")
protected void onReceivedData(String callbackId, JavaScriptObject jso) {
try {
// Read data
} catch (Exception e) {
// Handle Error
}
destroyCallbackmethod(callbackId);
}
/**
* Creates a native javascript callback.
* #param cscr to invoke the {#link #onReceivedData(String, com.google.gwt.core.client.JavaScriptObject)} on when the data has been loaded.
* #param callbackId DOM-Id to create the callback back.
*/
private native void createCallback(CrossSiteDomainRequest cscr, String callbackId) /*-{
$wnd[callbackId] = function(j) {
proxy.#com.test.package.client.CrossSiteDomainRequest::onReceivedData(Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;)(callbackId, j);
};
}-*/;
private native void removeCallback(String callbackId) /*-{
$wnd[callbackId] = null;
}-*/;
public static native Element getHead() /*-{
return $doc.getElementsByTagName('head')[0];
}-*/;
}
If you create a CrossSiteDomainRequest Object for the URL http://www.test.com/loadXDR.js
you have to evaluate the callbackId parameter and generate a java script which may looks like this:
callbackId({"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}});
The callbackId has to be replaced accordingly.

Resources