2

I'm trying to make an application that can help me post art in various platforms at once in a timed manner.

So what I'm trying to do is just get the authentication code from DeviantArt using the Authentication Code Grant from their API in PHP, then I'll take that code and put it on my application so I can use it to get the Access Token and post art on my account.

I've made the PHP code below to do a GET request to https://www.deviantart.com/oauth2/authorize and it successfully sent me to the authentication page. But when I log in to my account, it gives me a 403 Forbidden Access error. The API requires me to publish my app and whitelist the OAtuth2 Redirect URI, and I've already done that.

Here's the code in poster/assets/php/authDeviantArt.inc.php:

<?php
if(isset($_POST["submit"])){
    $result = file_get_contents("https://www.deviantart.com/oauth2/authorize?response_type=code&client_id=9685&redirect_uri=http://myipaddress:80/poster/requestAuthorization.php", false);
    echo $result;
} ?>

And here's the file in the URI that DeviantArt should redirect me (poster/requestAuthorization.php):

<?php
if(isset($_GET["code"])){
    echo $_GET["code"];
}
?>



<html>
    <head>
        <title>Authorization</title>
        <meta charset="utf-8">
    </head>
    <body>
        <form action="assets/php/authDeviantArt.inc.php" method="POST">
            <button type="submit" name="submit">Authorization DeviantArt</button>
        </form>
    </body>
</html>

UPDATE 01: I've removed the port from the URI in both the whitelist and the redirect_uri, and it's still giving me the 403 error when I log in. I also discovered that if I give the redirect_uri property a URI that's not whitelisted, it will show an error page instead of asking me to log in. I've also tried to ask it to redirect me to another webpage (youtube), with no success (still giving me the 403 error).

UPDATE 02: One of the answers has suggested that the error might be because I need to send a request with a "USER-AGENT" in the header and compress it. Now my code is like this:

<?php
if(isset($_POST["submit"])){
    $opts = array(
        'http' => array(
            'method'=>"GET",
            'header'=>"User-agent: ".$_SERVER["HTTP_USER_AGENT"]
        )
    );

    $context = stream_context_create($opts);
    $result = file_get_contents("https://www.deviantart.com/oauth2/authorize?response_type=code&client_id=9685&redirect_uri=http://myipaddress/poster/requestAuthorization.php", false, $context);
    echo $result;
}
?>

The code above still doesn't solve the problem, probably because I need to "compress" my HTTP GET request? I'm quite new, and I tried to do some research, but I couldn't find out how to do it.

UPDATE 03: Thanks to one of the answers below, I found out how to compress my request. Unfortunately, it didn't work. I will send the email to DeviantArt's Support team and see if they can help me. My code is like this for now:

<?php
    if(isset($_POST["submit"])){
        $opts = array(
            'http' => array(
                'method'=>"GET",
                'header'=>"User-Agent: ".$_SERVER["HTTP_USER_AGENT"]."\r\n".
                        "Accept-Encoding: gzip\r\n"
            )
        );

        $context = stream_context_create($opts);
        $result = file_get_contents("compress.zlib://https://www.deviantart.com/oauth2/authorize?response_type=code&client_id=9685&redirect_uri=http://myipaddress/poster/requestAuthorization.php", false, $context);
        echo $result;
    }
?>

3 Answers3

1

You might want to read this link and un/successful examples of which.

It seems to me that these variables are required:

curl https://www.deviantart.com/oauth2/token \
-d grant_type=authorization_code \
-d client_id=0 \
-d client_secret=mysecret \
-d redirect_uri=http://myapp.example/cb \
-d code=1234

Successful Example

{
  "expires_in": 3600,
  "status": "success",
  "access_token": "Alph4num3r1ct0k3nv4lu3",
  "token_type": "Bearer"
  "refresh_token": "3ul4vn3k0tc1r3mun4hplA",
  "scope": "basic"
}

Based on the example, maybe you are just missing client_secret variable, and if you wish, you might add a grant_type.

<?php
if(isset($_POST["submit"])){
    $result = file_get_contents("https://www.deviantart.com/oauth2/authorize?response_type=code&client_id=9685&redirect_uri=http://myipaddress:80/poster/requestAuthorization.php", false);
    echo $result;
} ?>

However, their error message does not seem to want these variables:

{"error":"invalid_request","error_description":"Request field validation failed.","error_details":{"response_type":"response_type is required","client_id":"client_id is required","redirect_uri":"redirect_uri is required"},"status":"error"}
Community
  • 1
  • 1
Emma
  • 27,428
  • 11
  • 44
  • 69
  • 1
    Thanks for responding. The first code you've shown me is to request an Access Token that I can use to publish stuff to DeviantArt. To get the Access Token, I need the authentication code (you can see that one of the variables is "code"). To get the code, I need to first do the User Authorization step from the link you've posted. When I do the GET, it sends me to the page to log in to my account and when I do that, it gives me a 403, instead of redirecting me the requestAuthorization.php with the code I need. That's the problem – Dragon Of War May 05 '19 at 17:45
  • 1
    I've removed the port and it's still giving me the 403 error when I log in. I also discovered that if I give the redirect_uri property a URI that's not whitelisted, it will show an error page instead of asking me to log in. So I conclude that the error is not because of the whitelist. – Dragon Of War May 05 '19 at 18:16
1

I cannot tell if you do it but you might be getting a 403 if you don't send a User Agent and if you don't use compression in your requests. IIRC at some point in the past they silently started enforcing both of these without prior notice. Was fun having everything fail suddenly.

To quote the DA Errors section

If you recieve 403 errors that contain an HTML response rather than JSON, please ensure your client is sending a User Agent header and using HTTP compression for the request, we reject any requests not meeting this requirement.

Pinkie Pie
  • 688
  • 7
  • 15
  • Thanks for responding. Check the UPDATE 02 in the question. – Dragon Of War May 05 '19 at 21:15
  • You can enable compression by setting the header field "Accept-Encoding" as "gzip" Maybe this question and its answers might help https://stackoverflow.com/questions/8581924/how-can-i-read-gzip-ed-response-from-stackoverflow-api-in-php/8582042#8582042 – Pinkie Pie May 06 '19 at 07:30
  • Hey. I found out the problem. It was unrelated with the link, but now I know how to do a compressed GET request when I need to. Thanks for the help! – Dragon Of War May 07 '19 at 22:45
0

I found out what was the problem. Apparently, I shouldn't be getting the contents of the authentication page and echoing in my page. Instead, I should be redirecting the user to the authentication page.

<?php
    if(isset($_POST["submit"])){
        header("Location: https://www.deviantart.com/oauth2/authorize?response_type=code&client_id=9685&redirect_uri=http://myipaddress/poster/requestAuthorization.php");
    }
?>