Creating Reddit Login Button in PHP

In this tutorial I will show you how to create a Reddit login button for your website using PHP.

What is OAuth?

OAuth is a protocol used to allow secure authorization to websites and applications to access user information. There are two versions of OAuth, 1.0 and 2.0. In this post we will use OAuth 2.0 to build a Reddit login system.

What is Reddit Log-In?

Reddit Log-in means asking user to grant access to his/her reddit information like email id, username etc. Once your website has been granted access and has all these information about the user it can allow the users to access protected pages on your website.

Setting up Directory and Files

Before we get started you need to create a PHP file named redirect.php. Place this file anywhere in your webspace.

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.
PHP
  • 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
PHP
  • 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
PHP
  • 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.
  • Article written by Narayan Prusty. Narayan is a web astronaut. He loves teaching and sharing ideas. When not coding he enjoys watching football. You will often find him at QScutter classes. He is the founder of QNimate
  • This doesn't seem to work. After I click authorize, the user_identity function does not return anything, and after var_dump'ing result in user_identity, I see it's because of a 400 - Bad Request error.
New question is currently disabled!