Google SignIn2 won't call the onsuccess callback - vue.js

I put a google signin button on my page using the "gapi.signin2.render" function. To this function I pass an object with the onsuccess handler.
When the user initially clicks on the button everything works as expected. The google signin popup appears. But after finishing the signin process nothing happens on my page.
After refreshing the page, the button triggers the auth process again. And as soon as the "Signed In" appears, the onsuccess handler gets called.
I looked at the network traffic and saw a response containing all the information. That means that everything should be configured correctly in the google console. Otherwise I wouldn't get the response, right?
This is my vue component:
<template>
...
<div id="google-signin-button" class="g-signin2"></div>
...
</template>
<script>
...
window.gapi.signin2.render('google-signin-button', {
onsuccess: this.onSignIn,
})
...
onSignIn: function(googleUser) { }
<script>
This is the index.html:
<meta name="google-signin-client_id" content="xxx.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js" async defer></script>
What can I do to get the onsuccess handler called on the initial signin?

Ok, i found it. Unfortunately i misunderstood the official documentation.
I had to load the auth2 module first:
window.gapi.load('auth2', () => {
window.gapi.signin2.render('google-signin-button', {
onsuccess: this.onSignIn,
})
})

Related

How to dispay flash message after redirect vue-router

I'm creating simple login logout application using vuejs and express. After user register successfully, I redirect them to page login by this.$router.push('/login'), and I want to display a flash message like 'Register sucess. Now log in!'
Here is my method
In Register.vue
this.$router.push("/login", () => {
console.log('Register success')
EventBus.$emit('registerSuccess')
});
In Login.vue
<div class="alert alert-success" role="alert" v-if="flashMsg">{{flashMsg}}</div>
data() {return {flashMsg: ''}}
created() {
console.log('Created component')
EventBus.$on("registerSuccess", () => {
console.log('Set flash msg')
this.flashMsg = "Now log in!"
});
},
It don't work. EventBus listen the emit but don't set any value to flashMsg.
Console
Register success
Set flash msg
Created component
Can someone tell me how to do this? Thank you
According to this, what you are looking for is not possible because you are changing routes before emitting an event and therefore it cannot be caught.
I suggest you try using localStorage/SessionStorage, Vuex or query strings.

Google OAuth2 SignIn method fires at page load

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);
});
});

How do we call a function within the html file of vuejs defined in the javascript file of vuejs without creating a button in the html file?

I pretty new to vuejs and am building a vuejs project. One of the tasks I am stuck at is, that I want to call a function written in the javascript part of vuejs from the html part of vuejs without creating any buttons or textboxes. I want to call this function as soon as my app starts. How do I achieve this? When I use mounted (vue lifecycle hook), the page it redirects to keeps refreshing. would appreciate some leads on this.
For example, I have a code:
<template>
<h1>Hello World!</h1>
<!--I WANT TO CALL THE auth0login function here. How do I do that without creating a button/text field,etc -->
</template>
<script>
export default {
data: () => ({
return : {
clientID: process.env.example
}
}),
methods:{
auth0login(){
console.log('logging in via Auth0!');
Store.dispatch('login');
}
}
}
</script>
I want to call the auth0login function defined in the script part in the html part above in order to execute the functionalities of the auth0login function. I want to do this without creating any buttons in the html file and simply just execute the auth0login function when the app launches.
How do I do this?
You need to call auth0login() only when you're not already logged I guess.
I think the reason is after user already logged in, they go back to the initial page, and the function in mounted() hook run again. Thats why they keep get redirect to login page. This not happen when you insert the button, because the button require user to click at it.
To fix this, you need to define a vuex state to store whether user has logged in or not, and in mounted() hook, just called it when they not login yet.
So. Instead of
mounted: function() { console.log('logging in via Auth0!'); this.auth0login() } }
Add a check login state
mounted() {
if(!this.$store.state.userLoggin) // here i define userLoggin and vuex state, you should update it to true whenever user successfully login
{ console.log('logging in via Auth0!'); this.auth0login() //only call it when user not loggin
}
}
And remember to update your vuex state.userLoggin when user successfully login in the auth0login() function

Execute page show and leave animations: transitions only fire occasionally

How can I execute animations upon navigating (via $router) to and from a page/url. Ie, how can I perform animations on show and on leave of a page? I will have different enter and leave animations for each page. The animations are complex thus we use javascript callbacks instead of css3 implementation
I have attempted the following but the transition callbacks dont fire every time. For some pages the callbacks fire for others they dont and they all have the exact code. It's quite weird.
Example MyPage.vue (could be Contact.vue, AboutUs.vue etc.):
<template>
<transition v-on:enter="enter" v-on:leave="leave">
<main>
<p>Foo</p>
</main>
</transition>
</template>
<script type="text/javascript">
import gsap from 'gsap' // include animation library
export default {
methods: {
enter: function (el, done) {
// I only see the text enter sometimes for a page. Its not consistently firing
console.log('enter')
done()
},
leave: function (el, done) {
// I only see the text leave sometimes for a page. Its not consistently firing
console.log('leave')
done()
}
}
}
</script>
Check this example : https://codesandbox.io/s/n38vz0pnzp
It's triggering as expected.
I added the appear prop which triggers the enter animation even for the first component mounting (when starting the app).

Using MSAL v0.1.3 with Aurelia for Authentication

I've found all kind of examples of using MSAL and even examples of using MSAL with SPA applications (generally Angular or React) but I'm struggling to get this to work with Aurelia.
I did the following to ensure that the library is actually working as expected.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/0.1.3/js/msal.min.js"></script>
<style>
.hidden {
visibility: hidden;
}
</style>
</head>
<body>
<div id="username"></div>
<div id="token"></div>
<button id="login" onclick="loginPopup()">Log In</button>
<button id="logout" class="hidden">Log Out</button>
<script>
var authClient = new Msal.UserAgentApplication("my v2 endpoint client id",null);
function loginPopup(){
authClient.loginPopup(["openid","user.readbasic.all"])
.then(token => {
authClient.acquireTokenSilent(["user.readbasic.all"])
.then(accessToken => {
updateUI(token);
},
error => {
authClient.acquireTokenPopup(["user.readbasic.all"])
.then(accessToken => {
updateUI(token);
},
error => {
console.log("Token Error: " + error)
})
})
},
error =>{
console.log("Login error " + error)
})
}
function updateUI(token){
var loginbutton = document.getElementById("login");
loginbutton.className = "hidden";
let usernamediv = document.getElementById("username");
let tokendiv = document.getElementById("token");
usernamediv.innerText = authClient.getUser().name;
tokendiv.innerText = token;
}
</script>
</body>
</html>
That code works great. You click the Log In button, the Login Popup is displayed, you select the user, enter your password and the popup disappears and the UI is updated appropriately with username and token.
Now I'm trying to add this into my Aurelia app as follows:
main.js
export async function configure(aurelia){
aurelia.use
.standardConfiguration()
.developmentLogging();
let msClient = new Msal.UserAgentApplication('my v2 endpoint client id",null);
aurelia.use.instance("AuthService",msClient);
await aurelia.start();
if(msClient.getUser()) {
await aurelia.setRoot(PLATFORM.moduleName("app"));
else
await aurelia.setRoot(PLATFORM.moduleName("login/login"));
login.js
export class Login {
static inject = [Aurelia, "AuthService"]
constructor(aurelia, auth){
this.authService = auth
this.app = aurelia
}
activate(){
//Also tried this code in constructor
this.authService.loginPopup(["openid","user.readbasic.all"])
.then(token => {
this.app.setRoot(PLATFORM.moduleName("app"))
});
}
}
However, with this code in place, the app loads and navigates to the login page which pops up the login popup. However, once the user enters/selects name and password, the popup screen does not go away. The app (behind the popup) seems to reload and navigate to the app.js viewmodel but the popup remains on the screen and appears to be asking the user to enter/select username.
I've also tried using loginRedirect rather than loginPopup with a similar result in that the app is constantly redirected to the login page even after authenticating.
I'm guessing this has to do with the way MSAL is trying to respond to the app and the way Aurelia is trying to handle navigation, etc but I can't figure out where things are going awry.
Any help would be greatly appreciated!
Use the attached() lifecycle callback
It seems like everything is working, but the popup isn't going away. It's hard to know why without seeing the code in action, but the first thing you'll want to try is moving the relevant code to the attached() callback, which is called once the view and view-model are bound and added to the DOM.
Do NOT return the login promise in activate()
If you returned the login promise in activate(), activation wouldn't complete until the promise resolved. However, app.setRoot() is being called when the promise resolves as well, which means that you would be starting a new navigation before the first one completed. This is bad.
activate() {
// THIS WOULD BREAK
return this.authService.loginPopup(["openid","user.readbasic.all"])
.then(token => {
this.app.setRoot(PLATFORM.moduleName("app"))
});
}
Use the detatched() lifecycle callback
If that doesn't work, the next thing to do is check to see if authService.loginPopup() is properly logging in and resolving. If so, you can always go ahead and manually remove the popup from the DOM in the case that the library wasn't cleaning up after itself. You should do this detatched() lifecycle callback.