How can I use the Google Sign In button with the gsi CodeClient (Authorization code flow)? - google-signin

The google sign in button doesn't render unless I use the google.accounts.id.initialize() method. However to use the authorization code flow I need to use create and use a CodeClient by calling google.accounts.oauth2.initCodeClient() and then manually call a .prompt() method on this client object.
So I can't see how I am meant to have the user click on the sign in button and then start an authorization code flow without having the user have to deal with two separate popup windows. The first to authenticate themselves and the second to authorize the back end service.
Additional context:
This is a single page application
I am using my own back end service
Google sign in is the only authentication option available

Related

Sign In With Google - Trigger sign in programatically instead of button

I'm trying to migrate to the new Sign In With Google and I'm missing one crucial functionality I was using previously.
Basicly my application is working with locally created application users. At one point in the application, the user is prompted to login with Google Account to confirm that he's the correct user that will do some Google API action. I was able to achieve that with following code from the soon deprecated Google Sign-In library:
const auth = gapi.auth2.getAuthInstance();
if (!auth.isSignedIn.get())
await auth.signIn({
prompt: "select_account",
login_hint: employeeEmail
});
...
And it worked just fine. Now all the above methods are being deprecated and there are no direct replacements, or at least I don't understand how to achieve the same result. I am able to confirm the user identity by checking the id token received by using:
google.accounts.id.initialize({/*options*/);
...
google.accounts.id.prompt();
But if there's no google session active for the user, nothing happens.
The only way to actually trigger the Sign In is to click the Google Sign In Button, rendered using:
google.accounts.id.renderButton(htmlElement, {/*options*/});
After the button is clicked, the sign in popup is shown and everything is fine, the callback of the initialize configuration is called and the flow is resumed.
The problem is, how do I trigger the Sign In popup programatically? All of the above starts with a specific button click on my website.
FYI
I actually managed to reproduce almost the same behavior with the new API. It might not be the most elegant way of doing this, but I replaced the signIn method from my post above with google.accounts.oauth2.initTokenClient. Even though it should be used to only receive the tokens, it will also create a valid Google session that then can be detected by using silent auth (prompt: "none");

How to display a loading icon when logging into Blazor server application?

I have a Blazor server application (great) with a Razor page login form (absolute pain in my backside).
Upon submitting the login form, in the PageModel class I have an OnPostAsync method which calls upon my API to sign in and obtain an auth token, but obviously there is an element of delay to this (quite bad in my case at the moment). As it is, my page shows almost no indication that it is doing anything at all after pressing login, whilst the API is being contacted the page sits there like the submit button hasn't even been pressed, which is obviously very bad for users because the first thing they will do is mash the submit button until they get a visual response (as I probably would to be fair).
How on earth do I do this in a Razor page? I've tried this and this, neither have worked. At the moment I don't particularly care what is shown or done, I just want it to do SOMETHING. The perfect solution for me is disabling the form and/or overlaying something to show that it's busy, but I'd take a basic "Loading..." message somewhere.
Is there any way of doing this?
It seems that it simply isn't possible to do with a Razor page in a Blazor server application, because there is nothing to update the UI, it's not like a Blazor component where there is a SignalR connection kept active between the server and the client. In the case of the login page, the page is served to the client and the connection is then severed, so the next action that occurs is the page submits the details it's holding to the server and expects the login result as a response.
Javascript should have worked and I don't know why it didn't, I added a script to change some of the UI elements upon submission of the form, but it seems the OnPostAsync method in the PageModel was being called first and whether the script was running or not it just wasn't updating the UI, I'm guessing because it's awaiting the response before doing anything. The alternative was to remove the login code from the PageModel and use an AJAX call instead, but I didn't really want to do this.
I've added an ILoginHandlerService, with a StoreLogin and RetrieveLogin. In the implementation it receives a login object containing the credentials, encrypts them and stores them in a private variable. This service is added as a singleton in the app startup class. The login page now calls the StoreLogin method with the submitted details, and redirects to a new "Logging in" page. This new page has a "form" with just a text element containing a please wait message, and a script which calls Post on the form upon loading.
The "Logging in" page's OnPostAsync is what actually performs the login. It calls upon an injected IAuthService to log in, without passing any details to it. The IAuthService implementation itself (added as a scoped service in app startup) gets injected with the ILoginHandlerService, then internally calls upon that service to supply the stored login object. The stored object is decrypted, nulled and returned to the IAuthService and is then submitted to my API, which then responds with the logged-in user token, that is returned to the "Logging in" page, which then calls upon HttpContext.SignInAsync, adding the received API token, and redirects the user to the home page, signed in.
This seems very convoluted to me and I'm not entirely sure it's correct. From what I understand of the above, once the credentials are submitted from the login form all future processing of the credentials should now be done server side and are never returned back to the client?

how to use firebaseui-web autoUpgradeAnonymousUsers?

How to use firebaseui-web autoUpgradeAnonymousUsers?
Situation:
Before a user is signed-in / logged in, this page could be rendered. However, after a user is signed, I could no longer display this page using the same sample code as https://github.com/firebase/firebaseui-web.
I have set autoUpgradeAnonymousUser: true. So what are the steps to use autoUpgradeAnonymousUser. It is not available in the demo app source code.
Before rendering FirebaseUI, you could call firebase.auth().signInAnonymously() to sign in on the Auth instance. And then pass the Auth instance to firebaseUI instance. If autoUpgrade config is turned on, when user click sign-in buttons, it would trigger the account linking to link google/facebook/password account to your anonymous account. However, you need to provide the SignInFailure callback in case there is merge conflict. Here you can find more detail and code sample: https://github.com/firebase/firebaseui-web#upgrading-anonymous-users

Is there anyway to create playlists on Spotify using a command line tool?

I want to create a playlist through the command line, but I appear to need to use the "Authorization Code Flow" method of authentication to be able to do this. The only way I can think to do that, is with a full web app through the browser, but I just want to make a command line tool without any of that hassle.
Is there a way to deal with this?
You do indeed need to use the Authorization Code Flow. However, that doesn't mean you need to build a web app.
Method 1: Prompt from command line, a la Spotipy
Check out the way Spotipy, a 3rd party Python library implements their authentication: https://github.com/plamere/spotipy. It uses the command line to prompt for authentication, then gets users to copy the URL back. This could be an easy workaround if you don't want to fully implement an authorization flow yourself. I recommend going through their quick start to get an idea of a non- web app implementation.
(They even have an example for "Create a playlist", maybe you can just use and build off that? https://github.com/plamere/spotipy/blob/master/examples/create_playlist.py)
Method 2: Get an access token for your account only
The Authorization Guide states the following:
Accessing your data without showing a login form
I want to interact with the web API and show some data on my website.
I see that the endpoints I need authorization, but I don’t need/want a
login window to pop-up, because I want to grant my own app access to
my own playlists once. Is there any way of doing this?
You basically need an access token and a refresh token issued for your
user account. For obtaining a pair of access token / refresh token you
need to follow the Authorization Code Flow (if you need a certain
scope to be approved) or Client Credentials (if you just need to sign
your request, like when fetching a certain playlist). Once you obtain
them, you can use your access token and refresh it when it expires
without having to show any login form.
So, if you only need access for your own account, grab any of the simple tutorials from the internet, follow it, and get an access token. You can then use that access token to make calls.

Facebook Connect Server-Side GetLoginStatus using ASP.NET C#

I am currently using the Facebook Javascript SDK and the Facebook C# SDK (soley for retrieving user graph objects).
Everything so far is going great except for the following scenario:
User logs into Facebook
User opens a new browser window and visits my
site
Using the Javascript SDK, I can use the FB.getLoginStatus method to determine if they are connected or not (which they are in this scenario as I have previously authorized my site/app for the facebook login).
However, I need to be able to detect upon the homepage of my site loading for the first time, ideally server-side, if we are in this 'connected' state, and if so, render some different content to screen (logged in vs not logged in).
I can't currently see a server-side method in the Facebook C# SDK that enables me to do the equivalent of FB.getLoginStatus (clientside).
I should point out that any subsequent changes to the users loginstatus is handled via subscribing to the auth.authResponseChange event and all is working fine there, but its the first time page load when the user first hits the site that's the problem.
There isn't a way to do this on the server with any Facebook SDK. You must detect the user's status with the Facebook Javascript SDK. The reason for this is because this information is stored in cookies that are either only readable by facebook.com or that are on you domain, but were set by Facebook and should not be parsed by your app.
You can parse the cookies on your domain if you like, but it isn't recommended because Facebook considers those cookies to be an internal implementation detail and does not guarantee their contents. They could change at any time and break your app.

Resources