Search code examples
grailsoauth-2.0facebook-oauthgrails-2.3

Exception in a Grails 2.3.8 app with facebook oauth2.0


I'm having the followings setup:

BuildConfig:

plugins {
  build ":tomcat:7.0.52.1"
  compile ":hibernate:3.6.10.13"
  compile ':spring-security-core:2.0-RC2'
  compile ':spring-security-oauth:2.0.2'
  compile ':spring-security-oauth-facebook:0.1'
}

Config:

grails.plugin.springsecurity.oauth.domainClass = 'com.mobilizr.OAuthID'

oauth{
  providers{
    facebook {
      api = org.scribe.builder.api.FacebookApi
      key = '111111'
      secret = '333veeerysecret23234234234'
      successUri = '/oauth/facebook/success'
      failureUri = '/oauth/facebook/error'
      callback = "${baseURL}/oauth/facebook/callback"
    }
  }
}

When I click the link:

<oauth:connect provider="facebook" id="facebook-connect-link">Facebook</oauth:connect>

I get the exception:

java.lang.IllegalArgumentException: Must provide a valid url as callback. Facebook does not support OOB

I have no clue, what should that mean. The page spring security oauth facebook doesn't give give too much details out. Does anyone have an idea, or maybe a working sample of FB-auth?


Solution

  • baseURL in the callback URL is your application server URL. Replace baseURL with your application server URL. e.g.,

    callback = "http://localhost:8080/mySampleApp/oauth/facebook/callback"
    

    and your error resolved.

    One more thing replace successUri and failureUri as well. e.g.,

    oauth {
      providers {
        facebook {
            api = org.scribe.builder.api.FacebookApi
            key = 'Your_Key'
            secret = 'Your_Secret'
            successUri = 'http://localhost:8080/mySampleApp/oauthCallback/success'
            failureUri = 'http://localhost:8080/mySampleApp/oauthCallback/error'
            callback = "http://localhost:8080/mySampleApp/oauth/facebook/callback"
        }
      }
    }
    

    and provide code to get data from Facebook. I have written code to get user info:

    import grails.converters.JSON
    import org.scribe.model.Token
    
    class OauthCallbackController {
    
    def oauthService
    
    def index() {}
    
    def success() {
        Token facebookAccessToken = (Token) session[oauthService.findSessionKeyForAccessToken('facebook')]
        if (facebookAccessToken) {
            def facebookResource = oauthService.getFacebookResource(facebookAccessToken, "https://graph.facebook.com/me")
            def facebookResponse = JSON.parse(facebookResource?.getBody())
    
            Map data = [id: facebookResponse.id, username: facebookResponse.username, name: facebookResponse.name, email: facebookResponse.email,
                    first_name: facebookResponse.first_name, last_name: facebookResponse.last_name, birthday: facebookResponse.birthday,
                    gender: facebookResponse.gender, link: facebookResponse.link, work: facebookResponse.work, hometown: facebookResponse.hometown,
                    education: facebookResponse.education]
    
            render data
        } else {
            flash.error = "Token not found."
            render view: '/index'
        }
    }
    
    def error() {
        render params
    }
    }
    

    Working Code Repository


    Hope this helps :-)