Get access token via Log in with google in unity - unity3d

I would like to be able to login with my google account in my unity game.
I've tried using Play Game Services, which imo would be the best solution, and I can log in and get name and ID and stuff, but I can't get the access token used, so I can verify who the user is on my server.
I have a server with a lot of player-data, that I can't put in Game Services, so I need to verify it's the correct user, and the ID is not safe enough.
How can I log in with google and get an access token in unity?
cheers

You can use this code to get token :
PlayGamesPlatform.Instance.Authenticate(success =>
{
if (success)
{
Debug.Log("Token :");
Debug.LogFormat("{0}", PlayGamesPlatform.Instance.GetAccessToken());
Debug.Log("End Of Token");
}
});
But you have to add a client id to your Google play services unity plugin.

Have you tried writing a custom Android plugin for your game?
You could get anything in your Unity game that you would be able to on a native Android app, and then pass that data to reference against your server.
They have pretty straightforward documentation for it:
http://docs.unity3d.com/Manual/PluginsForAndroid.html
I hope that helps!
Edit: Elaborated statement.

The PlayGamesPlatform.Instance.GetToken() will give you a string token, but can take a while to download, even several seconds. If the app setup is correct, it should populate after a while. Keep polling it whether it's null or empty, and it should eventually yield a valid token. The token is only good for 1 hour.

In order to access Google APIs on a backend web server on behalf of the current player, you need to get an authentication code from the client application and pass this to your web server application. This code can then be exchanged for an access token to make calls to the various APIs. For more details on this flow see: https://developers.google.com/identity/sign-in/web/server-side-flow
To get the Auth code: 1. Configure the web client Id of the web application linked to your game in the Play Game Console. 2. Call PlayGamesPlatform.GetServerAuthCode() to get the code. 3. Pass this code to your server application.
I am able to get the AuthCode and this code is given to the server and they generate the access token and authenticate my account.

Related

Using Google Cloud Speech and Unity, can't authenticate speech requests, but only on certain computers

This is the error Unity is spitting out in the logs, over and over:
Status(StatusCode=Unauthenticated, Detail="Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.")
More context is:
I use cloud speech for work and it's working fine everywhere except for one customer's computer. The app is built with Unity and uses the gRPC plugin to do the streaming variant of cloud speech. The customer is in another country but my first guess is that wouldn't matter, as we have other customers in the same country that don't have this issue.
I tried looking through the documentation Google provides for error codes and this one isn't in there. I looked through the troubleshooting section and saw something about authentication. I supply the credentials at runtime from a JSON file stored in the app. The code when using the credentials looks something like this:
googleCredential = GoogleCredential.FromJson(Utils.DecodeBase64(encodedCredentials));
var channel = new Grpc.Core.Channel(SpeechClient.DefaultEndpoint.Host, googleCredential.ToChannelCredentials());
var speech = SpeechClient.Create(channel);
I'm trying to gather more information here so we can narrow down our troubleshooting to help the customer get the app running. Like does this point towards a specific router/firewall setting kind of thing, etc?
Thank you.

Authentication needed when chat bot conversing with user

This got stuck in my head from many days, can anyone help or say at-least this is not at all possible?
I'm working on developing a chat bot using dialogflow which integrates multiple applications along with google home assistant, dialogflow, actions on google and an application which i want to manage using chat or voice commands. Until now its good and got amazed of features providing by google.
But i'm expecting one more feature. Don't know whether any alternatives available for this or not, but i tried exploring and reached to desert. Below are my requirements, if others think this is really unique and useful to them as well then i can say they are improvements or add-ons i'm expecting from DialogFlow.
Let's take an example of a chat bot which is serving users through google assistant and as a web bot as well. Now while conversing, intents may trigger web-hook in fulfillments which may require an authentication like OTP(Nope if anyone thought it for payments) which means registered users or limited users only can perform actions. This is same as we use roles and groups in all the applications.
The way google is sending google prompt to the user for logging into gmail, is there any way that we can collect PIN or OTP or PASSWORD through some notification sent to the users phone as some card's or input box like and html while conversing with chatbot through web or home assistant etc..., so that it helps in adding more security.
I recently worked in a chatbot project where I had to authenticate my users. I'm writing an article about it, but I'll tell you what I did:
First of all, I'm using OAuth 2.0 protocol to authenticate my users, but if you doesn't use OAuth, there's no problem, you could do something equivalent.
I'm using Authorization Code Grand flow.
Let's see the steps:
Step 1 - Authorization Url:
My bot generates an authorization url which contains all needed data to identify the conversation in callback moment. Like this one:
https://authorization-server.com/oauth/authorize
?client_id={your-client}
&response_type=code
&state={conversation_id: 123456789}
&redirect_uri={your-callback-url}
Notice that the state parameter contains the conversation_id which identifies your conversation, this state parameter will be back when users return to your handler.
Step 2 - User Authentication
When users click in this link, they'll be redirected to your login page at your authorization server.
Step 3 - Callback
After users get authenticated, they'll be redirect back to your handler (an endpoint which will receive the authorization code from authentication server and the state parameter).
When it received this authorization code, it'll be exchanged by an access token in authorization server.
Step 4 - Store token
In the final step, you already has an access token and the conversation_id parameter, you can store it in a database, in a cache or be stateless. Your rules!
In my case, I'm using Watson Assistant with Cloudant database, and I store those access tokens in my database. So, when users request something to my bot, it could get this token from database and pass to my back-end servers.
This kind of approach, I call "magic link". And you could improve it by shortening the url as bit.ly does.
I hope it could help you, feel free to ask me if you need.
Best
You probably don't want to implement the OTP scheme yourself. While you could do this, there are other systems already in place that will do this for you.
The best is the one that you reference - Google Sign In.
Fortunately, you can leverage Google Sign In for both your website (where you would get the user to sign in and then pass this information along as you do the Dialogflow calls) and for the Assistant (where Google will pass along an ID token, indicating it has authenticated the user).

Ionic 3 native facebook login process

I had just finished the login process in Ionic 3 with the native facebook login plugin. Everything seems to work fine.
I get my facebook data and store them with the storage plugin.
Here starts the weird part for me.
I want the next time the user opens the app to be able to pass the authenticate phase automatically and i am not sure which is the proper solution.
Solution 1
When the user login for the first time a store the data so the next time he opens the app in the app.component.ts i check if the data i stored(ex userId) exists.
storage.get('userID').then((val) => {
this.isLoggedIn = true;
this.setRoot(MainPage);
});
Solution 2
I make use of the getLoginStatus function and if returns response.status === 'connected' i assume that the user was authenticated before and the data i stored exists.
Is one of them consider as a better approach?
Do you use a different solution?
Do i need the access token for some reason in this situation or this is useful for a web app only?
I would say it depends on the security you are looking for, is your app dealing with sensitive informations ?
If no then you can simply store the userId (your solution 1) and you are good.
If you are dealing with sensitive data then you should consider to have a more secure system (as an example you have to consider that the user may loose its phone and so the user may want to cut off the access...)
To secure the process with facebook a possible way to go :
send the access_token you get from facebook authentication to a remote server where you can check it (here a link for more info)
save a token to your sever corresponding to your new user (a json web token for example)
send back this token and save it locally
to every authentication check that the token is still valid server side
I recommend you to read the tutorials written by Josh Morony :
https://www.joshmorony.com/using-json-web-tokens-jwt-for-custom-authentication-in-ionic-2-part-2/
https://www.joshmorony.com/creating-role-based-authentication-with-passport-in-ionic-2-part-2/
https://www.joshmorony.com/basic-security-for-ionic-cordova-applications/

How to manage session with ember framework?

I have been asked to use ember for front end and java rest services as the backend. I am trying to figure out how to manage session for a particular user.
i know there are couple of options like storing in the local store, cookie but they are error prone as some users might disable those features. I want to know what is the preferred approach in normal enterprise apps.
Mine app is simple 15 page app. i need to capture user, and some profile details.
Session are usually more of server side part. You have to just make sure whether the provided session is available or not for every transformed route and request. There is a library which takes care of authentication and authorization in ember https://github.com/simplabs/ember-simple-auth.

How to pass Facebook Id from client to server securely

I have a Facebook canvas app. I am using the JS SDK to authenticate the user on the browser-side and request various information via FB.api (e.g. name, friends, etc.).
I also want to persist some additional user information (not held on Facebook) to the database on my server by making an ajax call:
{ userFavouriteColour: "Red" }
To save this on the server and associate with the correct user, I need to know the Facebook uid and this presents a problem. How do I pass the uid from the client to the server.
Option 1: Add uid to the ajax request:
{ uid: "1234567890",
userFavouriteColour: "Red" }
This is obviously no good. It would be trivial for anyone to make an ajax request to my web service using someone else's Facebook Id and change their favourite colour.
Option 2: On the server, extract the uid from a cookie:
Is this even possible? I have read that Facebook sets a cookie containing the uid and access token but do I have access to this cookie on my domain? More importantly, can I securely extract the uid form the cookie or is this open to spoofing just like option 1.
Option 3: User server-side authentication on the server:
I could use the server-side authentication to validate the user identity on my server. But will this work if I am already using client-side authentication on the browser? Will I end up with two different access tokens? I would like to make FB.api requests from the browser so I need the access token on the client (not just on the server).
This must be a very common scenario so I think I'm missing something fundamental. I have read a lot of the Facebook documentation (various authentication flows, access tokens, signed_request, etc.) and many posts on SO, but I still don't understand how client-side authentication and server-side authentication play nicely together.
In short, I want to know the user's identity on the server but still make requests to the Facebook api from the client browser?
(I am using ASP.NET and the Facebook C# SDK on the server)
EDIT: Added bounty. I was hoping to get a more deifnitive, official recommendation on how to handle this situation, or even an example. As said, I have already read a lot of the official FB docs on authentication flows but I still can't find anything definitive on how client-side and server-side authentication work together.
Option 1:
The easiest way I can think of is to include the accessToken in JS and pass it with the ajax call.
Option 2:
Using the same as option 1, but instead of sending just the accessToken, send the signedRequest.
On the server side you can decode it using (TryParseSignedRequest method) which will give you the UserID :-)
Note: signedRequest is encrypted with the application Secret. you are the only one who should know it, so you are safe on that end.
Disclaimer:
I have no coding experience in C#, but a little search in google gave me this:
Facebook C# SDK for ASP.NET
Making AJAX Requests with the Facebook C# SDK
It's very simple actually.
When the user loads you app use the server side authentication, get the access token and load the user data by issuing an api request from the server.
On the server side you'll have everything you need and it's sandboxed.
When the page renders for the user, using the js sdk get the user authentication data, you should be able to use FB.getLoginStatus since the user already went through the server side authentication.
Now on the client side you also have an access token which you can use to get the user data from the graph api.
The two tokens will be different, and will also have different expiration, but that should not be a problem, both token should work properly as you'd expect them to.
Since both sides have their own token and a way to make requests to the api, there's no need to send any fb data between them.
So the 3rd option you mentioned, to me, sounds the best, and it's really simple to implement that too.
Edit
All facebook SDKs are just wrappers for http request since the entire fb api is made on http requests.
The SDKs just give you easy and shorter access to the data with out the need to build the url yourself (with all the different possible parameters), make the request and parse the response.
To be completely honest, I think that stop providing a way for the C# SDK to support server side authentication is a very bad decision.
What's the point in providing a SDK which does not implement the entire api?
The best answer to your question, from my experience, is to use both server and client side authentication, and since the C# SDK does not support it, my advice to you is to create your own SDK.
It's not complicated at all, I already implemented it for python and java (twice), and since you'll be developing it for your own needs it can be tailored for your exact needs, unlike a public SDK which should support all possible options.
2nd Edit
There's no need to create a completely new SDK, you can just "extend" the ones you're using and add the missing parts that you need, like sever side authentication support.
I don't know if it's language specific but using both server-side and client-side authentication does no harm.
You can work on option 2 but yes, that will be also vulnerable to spoofing.
Doing option 3, you will be having a single access token for that user session, so that would be the best choice according to me since you always have chance of spoofing when passing user information from client side.
I had exactly the same question recently. It's option 2. Check this post from the Facebook blog.
To be honest I am not enough of a hacker to know if you could spoof the UID in the cookie, but this seems to be the 'official' way to do it.
EDIT: to the other question under option 2, yes, I believe you have to access this cookie on your domain.