I'm working on a Unity C# project and trying to authenticate a request to Realtime Database using the id token Firebase returns after a user signs in, but it says the request is unauthorized. Here's my sign-in code (AuthResponse wraps the response body):
WWWForm form = new WWWForm();
form.AddField("email", email);
form.AddField("password", password);
using (UnityWebRequest www = UnityWebRequest.Post("https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=" + API_KEY, form))
{
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log($"Login failed: {www.error}");
callback(false);
}
else
{
AuthResponse data = www.downloadHandler.text.FromJson<AuthResponse>();
ID_TOKEN = data.idToken;
}
}
And my read request:
string url = $"{DATABASE_URL}{path}.json";
if (auth) url += $"?auth={ID_TOKEN}";
using (UnityWebRequest www = UnityWebRequest.Get(url))
{
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log($"Read failed: {www.error}");
}
}
My database has public rules and everything works without the auth parameter. What am I missing?
Edit: This is the token response:
{
"kind": "identitytoolkit#SignInWithPasswordResponse",
"localId": <LOCAL_ID>,
"email": <EMAIL>,
"displayName": "",
"idToken": <ID_TOKEN>,
"registered": true
}
This is the full read request url: https://<PROJECT_ID>.firebaseio.com/testing/flatString.json?auth=<ID_TOKEN>
instead of doing your own httppost use Firebase Unity SDK
Before you can use Firebase Authentication, you need to:
Register your Unity project and configure it to use Firebase.
If your Unity project already uses Firebase, then it's already registered and configured for Firebase.
If you don't have a Unity project, you can download a sample app.
Add the Firebase Unity SDK (specifically, FirebaseAuth.unitypackage) to your Unity project.
Related
I am trying to send login data to server from unity through node.js and node.js will return id of login user. but post does not work. C# Code
form.AddField("usernamePost" , username);
form.AddField("passwordPost" , password);
print(username + " " + inputPassword);
UnityWebRequest www = UnityWebRequest.Post(LoginURL,form);
yield return www.SendWebRequest();
//spinner.Dismiss();
string value= www.downloadHandler.text;
And this is nodejs code
app.use('/ownerLogin', (req,res) =>{
let username=req.query.ownerIdPost;
let userPassword=req.query.passwordPost;
console.log(username);
console.log(userPassword);
I have tried
req.param
req.params
req.body
It gives empty and undefined I also change request method to
app.get('/ownerLogin', (req,res) =>{.....
and
app.post('/ownerLogin', (req,res) =>{....
But nothing worked for me . Kindly help me
It worked on me using
NodeJS:
app.post(`/letlogin`, (req, res) => {
console.log(req.body.username);
});
Unity:
WWWForm formData = new WWWForm () ;
formData.AddField("username", "Barodar");
UnityWebRequest www = UnityWebRequest.Post("http://localhost:3001/letlogin/", formData);
yield return www.SendWebRequest();
I'm working in an Unity app that needs to connect to a Microsoft Dynamics 365 which uses OAuth2.0. I was trying using UnityWebRequest to retrieve an access token by calling:
https://login.microsoftonline.com/[TENANT_ID]/oauth2/v2.0/token
using something similar to this thread:
OAuth2 Authentication and Operations in Unity
And it works, I'm able to get and access_token, however, when I try to consume the service with the Bearer token, I always get "401 unauthorized".
I then tried to call instead:
https://login.microsoftonline.com/[TENANT_ID]/oauth2/v2.0/authorize
But when I do that, the response is the actual HTML code of the Microsoft login screen. As far I know, getting an auth code requires a user interaction right? but I've been able to get this done by using Microsoft.IdentityModel.Clients.ActiveDirectory package from NuGet in a console C# app without user interaction, so there must be a way right?
I would really appreciate your help on this! thank you!
UPDATE 1 - My code
Get access token
private IEnumerator GetAccessToken(Action<string> result)
{
Dictionary<string, string> content = new Dictionary<string, string>();
//Fill key and value
content.Add("scope", "https://graph.microsoft.com/.default");
content.Add("grant_type", "client_credentials");
content.Add("client_id", "xxxxx");
content.Add("client_secret", "xxxx");
UnityWebRequest www = UnityWebRequest.Post("https://login.microsoftonline.com/[TENANTID]/oauth2/v2.0/token", content);
//Send request
yield return www.Send();
if (!www.isError)
{
string resultContent = www.downloadHandler.text;
TokenClassName json = JsonUtility.FromJson<TokenClassName>(resultContent);
//Return result
result(json.access_token);
}
else
{
//Return null
result("");
}
}
Call API
private IEnumerator GetData(Action<string> result)
{
Dictionary<string, string> content = new Dictionary<string, string>();
//Fill key and value
content.Add("CustomerGroupId", "10");
UnityWebRequest www = UnityWebRequest.Post("https://[ENVIRONMENT].cloudax.dynamics.com/data/TestEntity", content);
string token = null;
yield return GetAccessToken((tokenResult) => { token = tokenResult; });
result(token);
www.SetRequestHeader("Authorization", "Bearer " + token);
www.Send();
if (!www.isError)
{
string resultContent = www.downloadHandler.text;
// Perform additional operations...
}
}
The resource is different for the token and the API call. In the token request, the resource is https://graph.microsoft.com, it's not your destination API. You should request the token for your destination API.
I was able to make a oauth 2 login with Unity3d on Microsoft graph, I requested this permission for my app:
https://graph.microsoft.com/files.readwrite.appfolder
After the usual code flow (redirect to url, permission from user, auth code exchanged for token code and token for bearer auth code) I was able to log in.
Problem is that the upload of small files does not work:
https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content
I think this is the best I can do:
string myData = File.ReadAllText(Application.persistentDataPath + "/" + "provaupload.json");
using (UnityWebRequest www = UnityWebRequest.Post("https://graph.microsoft.com/v1.0/me/drive/root:/AppTry/provaupload.json:/createUploadSession", myData)) {
www.SetRequestHeader("Authorization", "Bearer <code>");
www.SetRequestHeader("Content-Type", "application/json");
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError) {
Debug.Log(www.error + " " + www.downloadHandler.text);
} else {
Debug.Log("Upload complete! " + www.downloadHandler.text);
}
}
and I get this error:
Generic/unknown HTTP error {
"error": {
"code": "BadRequest",
"message": "Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format.",
"innerError": {
"request-id": "id",
"date": "2018-07-20T06:24:30"
}
}
I also tried the WWW class or Put instead of Post but I get "invalid API".
Maybe my problem is in the base url:
https://graph.microsoft.com/v1.0/me
or maybe it's in the path
root:/AppTry/provaupload.json
or maybe in the permission.
I don't really know.
If you know how to make a Rest call with Microsoft Graph and One drive (even not in unity3d and even if you don't know how to solve my specific problem) it would be great to get some example.
To upload file, use the UploadHandler. You must also encode the string as UTF8. As you mentioned in the comment section, it looks like you have to use PUT instead of POST and the url should be changed to something else.
Something more like this:
string myData = File.ReadAllText(Application.persistentDataPath + "/" + "provaupload.json");
string url = "https://graph.microsoft.com/v1.0/me/drive/root:/AppTry/provaupload.json:/content";
using (UnityWebRequest www = new UnityWebRequest(url, "PUT"))
{
byte[] dataToSend = new System.Text.UTF8Encoding().GetBytes(myData);
www.uploadHandler = (UploadHandler)new UploadHandlerRaw(dataToSend);
www.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
www.SetRequestHeader("Authorization", "Bearer <code>");
www.SetRequestHeader("Content-Type", "application/json");
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error + " " + www.downloadHandler.text);
}
else
{
Debug.Log("Upload complete! " + www.downloadHandler.text);
}
}
I'm getting the following exception when I build my game for android
WWW download had an error: java.lang.IllegalArgumentException: uri ==
null
Now I haven o idea why this is happening because it works fine in the editor. Here is the relevant code :
assetLoader.BundleURL = "ftp://user:pass#81.161.248.122/Unity-Uri/AssetBundles/seasonalcontent/christmas";
assetLoader.version = 1;
assetLoader.StartDownload();
and the actual download code :
IEnumerator DownloadAndCache()
{
// Wait for the Caching system to be ready
while (!Caching.ready)
yield return null;
// Load the AssetBundle file from Cache if it exists with the same version or download and store it in the cache
using (WWW www = WWW.LoadFromCacheOrDownload(BundleURL, version))
{
yield return www;
if (www.error != null)
throw new Exception("WWW download had an error:" + www.error);
AssetBundle bundle = www.assetBundle;
SeasonManager.assets = bundle.LoadAllAssets();
Debug.Log("Stop");
OnContentLoaded();
} // memory is freed from the web stream (www.Dispose() gets called implicitly)
}
Edit: I got this from the documentation : ftp:// protocol support is limited to anonymous downloads only. Is ftp not supported on android ?
Edit 2: As suggest in the comments I tried this and it results in a Login failed error :
IEnumerator makeRequest()
{
string authorization = authenticate("username", "pass");
string url = "ftp://ipgoeshere";
UnityWebRequest www = UnityWebRequest.Get(url);
www.SetRequestHeader("AUTHORIZATION", authorization);
yield return www.Send();
if (www.isError)
{
Debug.Log(www.error);
}
else
{
AssetBundle bundle = ((DownloadHandlerAssetBundle)www.downloadHandler).assetBundle;
SeasonManager.assets = bundle.LoadAllAssets();
}
}
string authenticate(string username, string password)
{
string auth = username + ":" + password;
auth = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(auth));
auth = "Basic " + auth;
return auth;
}
To clarify I've made sure that the username password and the server address are correct. I have simply removed them from the code here for obvious reasons.
Hi I am making a game in unity and I need to post information to my python flask server I think that the best method is to use the WWWForms in Unity C# but I can't seem to make it post. Here is my C# Unity Code:
IEnumerator Upload() {
WWWForm form = new WWWForm();
form.AddField("Username", "Stan");
form.AddField("Password", "123456");
using(UnityWebRequest www = UnityWebRequest.Post("http://myserver.com/newuser/", form)) {
yield return www.Send();
if(www.isError) {
Debug.Log(www.error);
}
else {
Debug.Log("Form upload complete!");
}
}
}
It alsways says "From upload complete" and I don't get any errors but when I check my SQL Database it hasn't received the information.
I am pretty sure that my server side code is right because I can post successfully to it through the Form but here is the code anyway:
Python Flask:
class Users(db.Model):
__tablename__ = "userstable"
userid = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(4096))
password = db.Column(db.String(4096))
#app.route("/", methods=["GET", "POST"])
def index():
return render_template("index.html")
#app.route("/newuser", methods=["GET", "POST"])
def NewUser():
if request.method == "GET":
return render_template("NewUser.html")
new_user = Users(username=request.form["Username"], password=request.form["Password"])
db.session.add(new_user)
db.session.commit()
return redirect(url_for('NewUser'))
Please Help, and if possible it would be nice to know how to do get requests as well, Thanks!
Stan.