Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directus Auth - 400 bad request using rest client but functional old school way?? #248

Open
kiritodragneel opened this issue Jul 5, 2024 · 7 comments

Comments

@kiritodragneel
Copy link

kiritodragneel commented Jul 5, 2024

Hey, so I am trying to connect and get an access Token from my directus instance.
If I use this code the code below then I get a 400 bad request error.

private async Task AuthenticateUserRest() {
        var url = "https://directus.mydomain.uk/auth/login";
        var email = "[email protected]";
        var password = "Mysupersecurepassword!";
        var mode = "cookie";
        
        //Tried the json as a string seen in below example, made no difference at all
        JSON requestBody = new JSON();
        requestBody.Add("email", email);
        requestBody.Add("password", password);
        requestBody.Add("mode", mode);
        
        RestClient.Request(new RequestHelper {
            Uri = url,
            Method = "POST",
            Headers = new Dictionary<string, string> {
                { "Accept", "application/json, text/plain, */*" }
            },
            ContentType = "application/json",
            Body = requestBody,
            Retries = 32
        }).Then(response => {
            if (response.StatusCode == 200) {
                Debug.Log("Response data: " + response.Text);
                var responseJSON = JSON.ParseString(response.Text);
                TOKEN = responseJSON.GetJSON("data").GetString("access_token");
                RestClient.DefaultRequestHeaders["Authorization"] = "Bearer " + TOKEN;
            } else {
                Debug.Log("Error data: " + response.Text);
            }
        }).Catch(err => {
            Debug.LogError("Error: " + err.Message);
        });
    }

However if i use this snippet then it works without issue

 private async Task AuthenticateUser() {
        var url = "https://directus.mydomain.uk/auth/login";
        var email = "[email protected]";
        var password = "mysupersecurepassword!";
        var mode = "cookie";
        var json = $"{{\"email\":\"{email}\",\"password\":\"{password}\",\"mode\":\"{mode}\"}}";
        var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Accept", "application/json, text/plain, */*");

        var content = new StringContent(json, Encoding.UTF8, "application/json");
        var response = await client.PostAsync(url, content);

        if (response.IsSuccessStatusCode){
            var responseData = await response.Content.ReadAsStringAsync();
            Debug.Log("Response data: " + responseData);
            JSON _responseJSON = JSON.ParseString(responseData);
            TOKEN = _responseJSON.GetJSON("data").GetString("access_token");
        }else{
            Console.WriteLine("Error: " + response.StatusCode);
            var errorData = await response.Content.ReadAsStringAsync();
            Debug.Log("Error data: " + errorData);
        }
    }
@jdnichollsc
Copy link
Member

Hey dude, what's the code of that JSON class?

@kiritodragneel
Copy link
Author

Hey, so I did try
var json = $"{{\"email\":\"{email}\",\"password\":\"{password}\",\"mode\":\"{mode}\"}}";

thinking something similar, however it still did not work, but it is this asset
https://assetstore.unity.com/packages/tools/input-management/total-json-130344

If it helps, if you add me on discord .muttley I can give you a username/password and my real domain so you can test too.

@jdnichollsc
Copy link
Member

Hey mate, as I know Body is only going to work with Serializable classes using the Unity utility internally, if you want to use another tools for JSON serialization I recommend using BodyString attribute instead 🫡

@kiritodragneel
Copy link
Author

kiritodragneel commented Jul 9, 2024

Hey mate, as I know Body is only going to work with Serializable classes using the Unity utility internally, if you want to use another tools for JSON serialization I recommend using BodyString attribute instead 🫡

So even if i change the body to this
Body = $"{{\"email\":\"{email}\",\"password\":\"{password}\",\"mode\":\"{mode}\"}}",

I still get HTTP/1.1 Bad Request.

In the interest of trial and error, I have made it like this, the same json code that works with the mentioned example above.

    private async Task AuthenticateUserRest() {
        var url = "https://directus.mydomain.uk/auth/login";
        var email = "[email protected]";
        var password = "mypassword!";
        var mode = "cookie";
        var json = $"{{\"email\":\"{email}\",\"password\":\"{password}\",\"mode\":\"{mode}\"}}";
        
        RestClient.Request(new RequestHelper {
            Uri = url,
            Method = "POST",
            Headers = new Dictionary<string, string> {
                { "Accept", "application/json, text/plain, */*" }
            },
            ContentType = "application/json, text/plain, */*",
            Body = new StringContent(json, Encoding.UTF8, "application/json"),
            Retries = 32
        }).Then(response => {
            if (response.StatusCode == 200) {
                Debug.Log("Response data: " + response.Text);
                var responseJSON = JSON.ParseString(response.Text);
                TOKEN = responseJSON.GetJSON("data").GetString("access_token");
                RestClient.DefaultRequestHeaders["Authorization"] = "Bearer " + TOKEN;
            } else {
                Debug.Log("Error data: " + response.Text);
            }
        }).Catch(err => {
            Debug.LogError("Error: " + err.Message);
        });
    }
    ```

@kiritodragneel
Copy link
Author

Okay so here is the full class code, hopefully it can help

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Leguar.TotalJSON;
using Proyecto26;
using TMPro;
using UnityEngine;

public class DirectusLinkTesting : MonoBehaviour {
    [SerializeField] TMP_Text result;
    [SerializeField] string URL;
    [SerializeField] private string TOKEN;
    
    private string email = "[email protected]";
    private string password = "mypassword";
    private string mode = "cookie";
    
    private async void Start() {
        await AuthenticateUserRest();
    }

    public void FetchData() {
        RestClient.DefaultRequestHeaders["Authorization"] = "Bearer " + TOKEN;
        RestClient.Get(new RequestHelper {
            Uri = URL,
        }).Then(response => {
            LoadData(response.Text);
        }).Catch(err => {
            Debug.LogError("Error: " + err.Message);
        });
    }
    
    void LoadData(string _response) {
        result.text = _response;
    }
    
    
    private async Task AuthenticateUser() {
        var url = "https://directus.mydomain.uk/auth/login";
        var json = $"{{\"email\":\"{email}\",\"password\":\"{password}\",\"mode\":\"{mode}\"}}";
        var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Accept", "application/json, text/plain, */*");

        var content = new StringContent(json, Encoding.UTF8, "application/json");
        var response = await client.PostAsync(url, content);

        if (response.IsSuccessStatusCode){
            var responseData = await response.Content.ReadAsStringAsync();
            Debug.Log("Response data: " + responseData);
            JSON _responseJSON = JSON.ParseString(responseData);
            TOKEN = _responseJSON.GetJSON("data").GetString("access_token");
        }else{
            Console.WriteLine("Error: " + response.StatusCode);
            var errorData = await response.Content.ReadAsStringAsync();
            Debug.Log("Error data: " + errorData);
        }
    }
    
    
    private async Task AuthenticateUserRest() {
        var loginurl = "https://directus.mydomain.uk/auth/login";
        var requestBody = new {
            email = email,
            password = password,
            mode = mode
        };
    
        RestClient.Request(new RequestHelper {
            Uri = loginurl,
            Method = "POST",
            Headers = new Dictionary<string, string> {
                { "Accept", "application/json, text/plain, */*" },
                { "Content-Type", "application/json" }
            },
            Body = JsonUtility.ToJson(requestBody),
            Retries = 3 
        }).Then(response => {
            if (response.StatusCode == 200) {
                Debug.Log("Response data: " + response.Text);
                var responseJSON = JSON.ParseString(response.Text);
                TOKEN = responseJSON.GetJSON("data").GetString("access_token");
                RestClient.DefaultRequestHeaders["Authorization"] = "Bearer " + TOKEN;
            } else {
                Debug.Log("Error data: " + response.Text);
            }
        }).Catch(err => {
            Debug.LogError("Error: " + err.Message);
        });
    }
}

I have AuthenticateUser() which works fine, that runs, and then i fetch data no issues, however trying to use AuthenticateUserRest always gets a 400 error, no matter what way i provide it the body, I get the same error, I changed how I gave it the content type, retries, everything I am at a loss.

@kiritodragneel
Copy link
Author

Just bumping this as still got same issue and can't find a fix

@maifeeulasad
Copy link
Collaborator

@kiritodragneel care to share it as a toy project?

Willing to help you, but it taks quite a while to setup the excat same thing.

GitHub would be best way to share your project (Only share the necessary part).

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants