Google OAuth2 SignIn method fires at page load - google-oauth

I have used the official button for Google SignIn:
SignIn Page:
<div class="g-signin2" data-onsuccess="AuthenticateGoogleUser"></div>
function AuthenticateGoogleUser(googleUser){
.....
capture the user info and redirect to Home page
.....
}
When configuring for the credentials, I have set the redirection URL to the signin page.
This is how the Signout happens for the app:
function SignOutGoogleUser() {
if (gapi != null && gapi != undefined &&
gapi.auth2 != null && gapi.auth2 != undefined) {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
auth2.disconnect();
....Redirect to Home page...
});
}
}
The methods work fine. If I signout, will be redirected to home page.
But, when I manually browse the SignIn page after signout, the AuthenticateGoogleUser method is triggered and I am auto signed into the app (with google account).
The AuthenticateGoogleUser method should be only triggered on the button click. Is that right.
But here it is being triggered on load of SignIn page. Is that expected. Can this be stopped.
I'm using MVC C# as backend.

Without seeing all of your code, I am working on the assumption that you have not placed the function in a document ready wrapper and made sure to only kick it off on a button click or other event from which you would like to have it fire. As it stands now, it will fire on that page load.
$(document).ready(function(){
$("btnLogin").click(function(){
AuthenticateGoogleUser(googleUser);
});
});

Related

why is facebook js sdk web login callback not being called or called too early?

the problems
fb:login-button: with it, I can't log in.
FB.login(): with calling it by clicking a button, I'm able to log in but the callback function called too early before I log in or sign up so passes an unknown state response.
In case of fb:login-button
with facebook logged out, facebook login pop up pops up and when I log in, nothing happens(FB.getLoginStatus returns unknown state).
with facebook logged in, the pop up just flashes away and nothing happens(FB.getLoginStatus returns unknown state).
after both operation, checkLoginState() logs {authResponse: null, status: 'unknown'} neither status: 'not-authorized' or status: 'login'. It means I don't succeed to login I guess. Is that why the buttons onlogin callback is not called? (Cause it's called on login event)
In case of FB.login()
with facebook unknown state, when I click the button, the callback function is called before I login. It results passing unknown state response.
with FB.login() in console, FB.getLoginStatus returns successful login response.
Here is my html code
<body>
<script>
window.fbAsyncInit = function () {
FB.init({
appId: '...',
cookie: true,
xfbml: true,
version: 'v13.0'
});
FB.AppEvents.logPageView();
checkLoginState();
};
function checkLoginState() {
FB.getLoginStatus(function (response) {
statusChangeCallback(response);
});
}
function statusChangeCallback(response) {
console.log(response);
}
(function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement(s);
js.id = id;
js.src = "https://connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
function facebooklogin(){
FB.login(function(response){
statusChangeCallback(response);
});
}
function facebooklogout(){
FB.logout(function(response){
statusChangeCallback(response);
});
}
</script>
<fb:login-button scope="public_profile,email" onlogin="checkLoginState();">
</fb:login-button>
<button onclick="facebooklogin();">fb-login</button>
Any answer would be appreciated.
I found the answer.
The keypoint is FB.logout function leaves a cookie which prevents anymore login attemps. like fblo_51245583...=y.
With the cookie,
if you are logged in facebook and try to login your web then the pop-up will disappear very quickly.
if you are not logged in facebook and try to login your web while the pop-up prompts you to login, the callback function will be called with unknown state response(I guess the logout cookie automatically deny the login attempt at all). and whether you succeed to login in facebook or not it takes no effect on the web.
But I still don't know why the fb:login-button doesn't work.
And when The callback function is still executed earlier than my log-in process.
My goal is
When users log in first time using facebook, they are signed up automatically with their uid value from authResponse.
While they are accepting or loggin in facebook, the callback function should wait until they accept/reject or login/not like event-driven.
But as I understand FB.login functions callback parameter doesn't wait for the action but just wait for a response from the facebook server.
So I need other approaches.
use event subscription refer to https://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/v13.0

Authentication with Angular 5

I have a login page and I need to go to my home page after successful login. That login functionality login to a ldap server and send a response whether the authentication is success or not. I don't want that to keep in localstorage since this app has only two pages. login and home. When login success it should redirect to home page, if not it should redirect to again to the login page.
And please the console.log in the browser, "inside auth guard true" prints thousands times..
The only code I have in my app.component.html is <router-outlet></router-outlet>
In the canActivate(), all you need to do is return true or false. When you are redirecting it to home from inside the function you are entering into an infinite loop.
This is because on redirecting to home the canActivate() gets called and its expects a boolean return value. If the value is false, it won't load the component.
canActivate() {
if (this.authService.loggedIn) {
console.log('Inside Auth Gaurd');
return true;
}
console.log('auth gaurd false path');
return false;
}
For more detail on canActivate() refer this

Google+ signout without dialog popup

I have a signout button on my page that I'm initiating this way:
$('#logout').click(function() {
gapi.auth.signIn({
'callback': function(authResult) {
if (authResult['status']['signed_in']) {
gapi.auth.signOut();
} else {
// second pass, signout succesful
}
}
})
});
This ends up making two calls out to Google (first to validate that user is already logged in, second to sign out), thus the two passes through the callback code. This also causes the Google+ login window to briefly popup.
Is there a way to just call gapi.auth.signOut() directly without the signIn step? I have the user's Google+ id (and also access_token), if that helps.
You don't need to call the gapi.auth.signIn() every time you want to sign out. just call the gapi.auth.signOut() from anywhere to initiate the sign-out process from your app (but still signed in to Google in other tabs, which is good practice).
Example would be to just attach the gapi.auth.signOut() event to an onclick event on a button;
<button onclick="gapi.auth.signOut();">Sign out</button>

Facebook JS SDK FB.Login function

In my website, I have a button for "facebook connect", which when clicked on, triggers the following code:
<script type="text/javascript">
$(document).ready(function(){
console.log(<?=(isLoggedIn()+0)?>);
$("#fbconnect").click( function(){
FB.login(function(response) {
alert(JSON.stringify(response.authResponse));
if (response.authResponse) {
window.location = window.location;
alert('Welcome! Fetching your information.... ');
} else {
alert('User cancelled login or did not fully authorize.');
}
}, {scope: 'email,user_likes'});
} );
});
</script>
The button works well: it shows the facebook login dialog, and then alerts the appropriate message. However, when I refresh the page, the user is still logged out both server-side and client-side. Do I need to handle the access token and cookies myself or does the javascript SDK take care of that? If the latter, then why doesn't this code work?
Thank you.
UPDATE 1:
It works perfectly on localhost with Firefox, and on the server with all browsers. So the problem exists only for chrome and on localhost. Is there some chrome security setting that prevents cookies from being saved for localhost?

Refresh MVC view after logging in using Angular

Working with the Breeze Angular SPA template found here, http://www.breezejs.com/samples/breezeangular-template, I'm trying to update a menu that changes after user authenticates.
My example is slightly different from the default template in that I've moved the Login and Register views into modal windows. When the modal closes after a successful login, the menu, which is in the MVC View (and not the Angular View) does not update as a complete page refresh does not occur.
In the SPA template, authentication is required before entering the SPA, then a hard redirect/refresh occurs and the SPA is loaded. In my case, you could be browsing views/pages in the SPA before authenticating.
MVC View Code Snippet (Views/Home/Index.cshtml)
...
<li>
#if (#User.Identity.IsAuthenticated)
{
User Logged In: #User.Identity.Name
}
else
{
User Logged In: Annon
}
</li></ul>
<div ng-app="app">
<div ng-view></div>
</div>
....
I have working the root redirect, after login, the page hard refreshes if json.redirect is set to '/'. However, if its set to the current page, i.e. '#/about', Angular handles the routing and therefore no hard refresh occurs, thus the menu is not updated.
Ajax Login Code Snippet (App/ajaxlogin.js)
... part of login/register function
if (json.success) {
window.location = json.redirect || location.href;
} else if (json.errors) {
displayErrors($form, json.errors);
}
...
Is this possible to do using my current setup? Or do I need to move the menu somewhere inside the SPA and use Angular to determine what menu to show? If the latter, direction in how to best do this? I'm new to both Angular and Breeze.
The TempHire sample in Breeze has a really good way of handling authentication for a SPA (in my opinion at least!) Granted this is using Durandal so you will need to adapt it to Angular, but they are both frameworks doing the same basic principles so good luck! -
Basically, the Controller action has an annotation [Authorize] on the action that the prepare method is calling on the entitymanagerprovider. If a 401 is returned (not authorized) the SPA takes the bootPublic path and only exposes a login route to the user. When the login is successful, the login method tells the window to reload everything, at which time the authorization passes, and the bootPrivate method is called -
shell.js (Durandal, but should be adaptable)
//#region Internal Methods
function activate() {
return entitymanagerprovider
.prepare()
.then(bootPrivate)
.fail(function (e) {
if (e.status === 401) {
return bootPublic();
} else {
shell.handleError(e);
return false;
}
});
}
function bootPrivate() {
router.mapNav('home');
router.mapNav('resourcemgt', 'viewmodels/resourcemgt', 'Resource Management');
//router.mapRoute('resourcemgt/:id', 'viewmodels/resourcemgt', 'Resource Management', false);
log('TempHire Loaded!', null, true);
return router.activate('home');
}
function bootPublic() {
router.mapNav('login');
return router.activate('login');
}
login.js -
function loginUser() {
if (!self.isValid()) return Q.resolve(false);
return account.loginUser(self.username(), self.password())
.then(function() {
window.location = '/';
return true;
})
.fail(self.handleError);
}
The account.loginUser function is basically just an ajax call that passes credentials to the account controller and returns a success or failure. On success you can see the callback is fired for window.location = '/' which does a full reload. On failure simply show an alert or something.