Creating Reddit Login Button in PHP

Creating a Reddit App

If your website is allowing login using Reddit then your website is considered as an Reddit app. So you have your website ready now its time to register you website as a Reddit app. Follow this steps to create a reddit app:
  1. Visit Reddit apps page.
  2. Click on Create an App button.
  3. Now fill the form. Choose app type as web app and for redirect URI pass URL pointing to the redirect.php file.
After you have created a app you will have app id and app secret
reddit-app

Creating Login with Reddit Button

When user clicks on Login button you need to run this code to redirect user to Reddit website so that user can inform reddit to provide you profile information.
 
1
2
3
4
5
6
7
8
9
10
11
<?php

    $nonce = rand();
    $redirect_uri = "";
    $client_id = "";

    setcookie("reddit_login_nonce",$nonce);

    header("Location: " . "https://ssl.reddit.com/api/v1/authorize?client_id=". $client_id ."&response_type=code&state=". $nonce ."&redirect_uri=". $redirect_uri ."&duration=permanent&scope=identity");

?>
You should generate a unique, possibly random, string called as nonce for each authorization request. This value will be returned to you when the user visits your REDIRECT_URI after allowing your app access – you should verify that it matches the one you sent. This ensures that only authorization requests you’ve started are ones you finish.
Scopes represent the list of permissions for the app. For the last query parameter you need to pass a comma separated list of permissions. All possible permissions are: modposts, identity, edit, flair, history, modconfig, modflair, modlog, modposts, modwiki, mysubreddits, privatemessages, read, report, save, submit, subscribe, vote, wikiedit, wikiread
Populate the $client_id and $redirect_uri variables.

Redirecting back to the App

Once user has given access to the app, Reddit will redirect user back to the redirect URI. Now you need to retrieve an access token which acts like a permission to get user information.
In the redirect.php file you can retrieve access token by running this code
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php

    $client_id = "";
    $client_secret = "";
    $username = "";

    if(isset($_GET["error"]))
    {
        //error occured
        echo $_GET["error"];
    }
    else
    {
        //validate nonce
        if($_COOKIE["reddit_login_nonce"] == $_GET["state"])
        {
            //valid nonce

            //now make a post request with one time code to generate access token
            $url = "https://ssl.reddit.com/api/v1/access_token";
            $fields = array("grant_type" => "authorization_code", "code" => $_GET["code"], "redirect_uri" => "http://labs.qnimate.com/reddit-login/redirect.php");

            foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
            rtrim($fields_string, '&');

            $ch = curl_init();

            curl_setopt($ch,CURLOPT_URL, $url);
            curl_setopt($ch,CURLOPT_POST, count($fields));
            curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
            curl_setopt($ch, CURLOPT_USERPWD, $client_id.":".$client_secret);
            curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);

            $result = curl_exec($ch);
            $result = json_decode($result);

            curl_close($ch);

            //this is the access token which will used to retrieve user information. You can store this token in database and use it in future.
            $access_token = $result->access_token;
            $refresh_token = $result->refresh_token;
        }
        else
        {
            //invalid nonce
            echo "Please try to login again";
        }
    }
?>
Populate variable $client_id,$client_secret and $username. $username represents the developer account username.
Finally we got $access_token and $refresh_token. $access_token usually expires in 2 hours therefore $refresh_token is used to get a new access token after every 2 hours.

Retrieving Username

We can now retrieve or post any data on behave of the user by using Reddit Rest API.
This is an example to get Reddit username
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php

    function user_identity($access_token, $refresh_token)
    {
        //lets retrieve username of the logged in user
        $user_info_url = "https://oauth.reddit.com/api/v1/me";

        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL,$user_info_url);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: bearer ".$access_token, "User-Agent: flairbot/1.0 by ".$username));
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);


        $result = curl_exec($ch);
        $result = json_decode($result);

        if(isset($result->error))
        {
            //access token has expired. Use the refresh token to get a new access token and then make REST api calls.
            $url = "https://ssl.reddit.com/api/v1/access_token";
            $fields = array("grant_type" => "refresh_token", "refresh_token" => $refresh_token);

            foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
            rtrim($fields_string, '&');

            $ch = curl_init();

            curl_setopt($ch,CURLOPT_URL, "https://ssl.reddit.com/api/v1/access_token");
            curl_setopt($ch,CURLOPT_POST, count($fields));
            curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
            curl_setopt($ch, CURLOPT_USERPWD, $client_id.":".$client_secret);
            curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);

            $result = curl_exec($ch);
            $result = json_decode($result);

            //new access token
            $access_token = $result->access_token;

            curl_close($ch);

            $user_info_url = "https://oauth.reddit.com/api/v1/me";

            $ch = curl_init();
            curl_setopt($ch,CURLOPT_URL,$user_info_url);
            curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: bearer ".$access_token, "User-Agent: flairbot/1.0 by ".$username));
            curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);


            $result = curl_exec($ch);
            curl_close($ch);

            $result = json_decode($result);
            echo $user_name = $result->name;
        }
        else
        {
            echo $user_name = $result->name;
        }

        curl_close($ch);   
    }

Integrating Reddit Login in WordPress

WordPress is made on PHP therefore all code will be same for authorizing user and getting profile information. To create a redirect URL in WordPress use WordPress AJAX API.

Final Thoughts

If you want to more than just Login then increase the permissions in permission list and store the access token and refresh token in database for further use. Make sure you update the access token when its refreshed. Don’t share the client secret with anyone.

No comments:

Post a Comment