Skip to content

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

@kiritodragneel

Description

@kiritodragneel

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 = "myemail@mydomain.com";
        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 = "myemail@mydomain.com";
        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);
        }
    }

Activity

jdnichollsc

jdnichollsc commented on Jul 6, 2024

@jdnichollsc
Member

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

kiritodragneel

kiritodragneel commented on Jul 6, 2024

@kiritodragneel
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

jdnichollsc commented on Jul 8, 2024

@jdnichollsc
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

kiritodragneel commented on Jul 9, 2024

@kiritodragneel
Author

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 = "richard@mydomain.com";
        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

kiritodragneel commented on Jul 9, 2024

@kiritodragneel
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 = "richard@domain.com";
    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

kiritodragneel commented on Jul 14, 2024

@kiritodragneel
Author

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

maifeeulasad

maifeeulasad commented on Sep 8, 2024

@maifeeulasad
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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @jdnichollsc@kiritodragneel@maifeeulasad

        Issue actions

          Directus Auth - 400 bad request using rest client but functional old school way?? · Issue #248 · proyecto26/RestClient