Adding Tumblr to HWIOAuthBundle

Tumblr HWIOAuthI recently needed to add in Tumblr social authentication to a Symfony project. I made use of the excellent HWIOAuthBundle, which made the whole process a breeze.

Unfortunately, out of the box, there is no direct support for Tumblr.

However, no fear, as manually adding support in is simple enough.

Follow the installation instructions through to the end of Step 2. At the bottom of the section on Configuring Resource Owners is the option for ‘Others‘.

To get this to work, it’s mainly a bit of back and forth between the Tumblr API docs and your config.yml file, so let me spare you the time:

hwi_oauth:
    # list of names of the firewalls in which this bundle is active, this setting MUST be set
    firewall_name: main # important to change this to match the firewall you are adding hwioauth too
    resource_owners:
        tumblr:
            type:                oauth1
            client_id:           your_tumblr_api_client_id_here
            client_secret:       your_tumblr_api_client_secret_here
            access_token_url:    https://www.tumblr.com/oauth/access_token
            authorization_url:   https://www.tumblr.com/oauth/authorize
            request_token_url:   https://www.tumblr.com/oauth/request_token
            infos_url:           https://api.tumblr.com/v2/user/info
            scope:               "read"
            user_response_class: HWI\Bundle\OAuthBundle\OAuth\Response\PathUserResponse
            paths:
                identifier:     response.user.name
                nickname:       response.user.name
                realname:       response.user.name

The paths section is interesting.

We must specify at least these three for HWIOAuthBundle to not error out.

What I’m doing here is using a dotted array access format. Kinda confusing sounding, but really what this is saying is : $response[‘user’][‘name’] .

Why the same data for each field?

Well, Tumblr doesn’t return much in the way of account data here.

You can see the full output from Tumblr here:

PathUserResponse.php on line 122:
array:2 [▼
  "meta" => array:2 [▶]
  "response" => array:1 [▼
    "user" => array:5 [▼
      "name" => "futuristicallycrookedbread"
      "likes" => 0
      "following" => 6
      "default_post_format" => "html"
      "blogs" => array:1 [▼
        0 => array:29 [▼
          "title" => "Untitled"
          "name" => "futuristicallycrookedbread"
          "posts" => 4
          "url" => "http://futuristicallycrookedbread.tumblr.com/"
          "updated" => 1441562102
          "description" => ""
          "is_nsfw" => false
          "ask" => false
          "ask_page_title" => "Ask me anything"
          "ask_anon" => false
          "followed" => false
          "can_send_fan_mail" => true
          "is_blocked_from_primary" => false
          "share_likes" => true
          "likes" => 0
          "twitter_enabled" => false
          "twitter_send" => false
          "facebook_opengraph_enabled" => "N"
          "tweet" => "N"
          "facebook" => "N"
          "followers" => 0
          "primary" => true
          "admin" => true
          "messages" => 0
          "queue" => 0
          "drafts" => 0
          "type" => "public"
          "subscribed" => false
          "can_subscribe" => false
        ]
      ]
    ]
  ]
]

This is the result of using Symfony’s VarDumper component on line 122 of PathUserResponse.php .

How did I know to add the dump($response); statement in there?

Well, we specified in the config.yml file that we are expecting a User Response to be:

user_response_class: HWI\Bundle\OAuthBundle\OAuth\Response\PathUserResponse

I just opened up that file and added in the dump, using the $response variable that had been defined earlier on line 113.

There is a little bit of extra config in security.yml :

security:
    providers:
        social_user_provider:
             id: oauth_user_provider

    firewalls:
        main:
            anonymous: ~
            oauth:
                resource_owners:
                    tumblr:        "/login/check-tumblr"
                login_path:        /login
                use_forward:       false
                failure_path:      /login
                oauth_user_provider:
                    service: oauth_user_provider

    access_control:
        - { path: ^/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/connect, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, role: ROLE_USER }

Alongside the other HWIOAuth routes, you will need to add in one for Tumblr:

# app/config/routing.yml - or where ever you are storing routes
tumblr_login:
    path: /login/check-tumblr

The oauth_user_provider  service must exist, so here is my definition:

# services.yml (or where ever)
services:
    oauth_user_provider:
        class: AppBundle\Model\OAuthUserProvider

This should work for other social auth providers, with only a little modification. As much as this looks like loads of config (hey, it’s a Symfony project!), it’s actually really pretty easy to add in new social providers. I was pleasantly surprised.