5 date: "2016-01-26T16:05:28+00:00"
6 guid: http://juplo.de/?p=671
18 title: 'Develop a Facebook-App with Spring-Social – Part VI: Sign In Users Through The Canvas-Page'
19 url: /develop-a-facebook-app-with-spring-social-part-06-sign-in-users-through-the-canvas-page/
22 In this series of Mini-How-Tow's I will describe how to develop a facebook app with the help of [Spring-Social](http://projects.spring.io/spring-social/ "Learn more about Spring-Social")
24 In [the last part of this series](/develop-a-facebook-app-with-spring-social-part-05-refactor-the-redirect-logic/ "Read part 5 of this series"), we refactored our authentication-concept, so that it can be replaced by Spring Security later on more easy.
26 In this part, we will turn our app into a real Facebook-App, that is rendered inside Facebook and signs in users through the `signed_request`.
28 ## The Source is With You
30 You can find the source-code on [/git/examples/facebook-app/](/git/examples/facebook-app/ "Link for cloning")
31 and [browse it via gitweb](/gitweb/?p=examples/facebook-app;a=summary "Browse the source-code now").
32 Check out `part-06` to get the source for this part of the series.
34 ## What The \*\#&! Is a `signed_request`
36 If you add the platform **Facebook Canvas** to your app, you can present your app inside of Facebook.
37 It will be accessible on a URL like **`https://apps.facebook.com/YOUR_NAMESPACE`** then and if a (known!) user accesses this URL, facebook will send a [`signed_request`](https://developers.facebook.com/docs/reference/login/signed-request "Read more about the fields, that are contained in the signed_request"), that already contains some data of this user an an authorization to retrieve more.
39 ## Sign In Users With `signed_request` In 5 Simple Steps
41 As I first tried to extend the [simple example](http://spring.io/guides/gs/accessing-facebook/ "Read the original guide, this article-series is based on"), this article-series is based on, I stumbled across multiple misunderstandings.
42 But now, as I guided you around all that obstacles, it is fairly easy to refine our app, so that is can sign in users through the signed\_request, send to a Canvas-Page.
46 1. Add the platform "Facebook Canvas" in the settings of your app and choose a canvas-URL.
47 1. Reconfigure your app to support HTTPS, because Facebook requires the canvas-URL to be secured by SSL.
48 1. Configure the `CanvasSignInController`.
49 1. Allow the URL of the canvas-page to be accessed unauthenticated.
50 1. Enable Sign-Up throw your canvas-page.
52 That is all, there is to do.
53 But now, step by step...
55 ## Step 1: Turn Your App Into A Canvas-Page
57 Go to the settings-panel of your app on [https://developers.facebook.com/apps](https://developers.facebook.com/apps "Log in to your developer-account on Facebook now") and click on _Add Platform_.
58 Choose _Facebook Canvas_.
59 Pick a secure URL, where your app will serve the canvas-page.
61 For example: `https://localhost:8443`.
63 Be aware, that the URL has to be publicly available, if you want to enable other users to access your app.
64 But that also counts for the Website-URL `http://localhost:8080`, that we are using already.
66 Just remember, if other people should be able to access your app later, you have to change these URL's to something, they can access, because all the content of your app is served by you, not by Facebook.
67 A Canvas-App just embedds your content in an iFrame inside of Facebook.
69 ## Step 2: Reconfigure Your App To Support HTTPS
71 Add the following lines to your `src/main/resources/application.properties`:
75 server.ssl.key-store: keystore
76 server.ssl.key-store-password: secret
80 I have included a self-signed `keystore` with the password `secret` in the source, that you can use for development and testing.
81 But of course, later, you have to create your own keystore with a certificate that is signed by an official certificate authority, that is known by the browsers of your users.
83 Since your app now listens on `8443` an uses `HTTPS`, you have to change the URL, that is used for the platform "Website", if you want your sign-in-page to continue to work in parallel to the sign-in through the canvas-page.
85 For now, you can simply change it to `https://locahost:8443/` in the settings-panel of your app.
87 ## Step 3: Configure the `CanvasSignInController`
89 To actually enable the [automatic handling](https://developers.facebook.com/docs/games/gamesonfacebook/login#usingsignedrequest "Read about all the cumbersome steps, that would be necesarry, if you had to handle a signed_requst by yourself") of the `signed_request`, that is, decoding the `signed_request` and sign in the user with the data provided in the `signed_request`, you just have to add the `CanvasSignInController` as a bean in your `SocialConfig`:
93 public CanvasSignInController canvasSignInController(
94 ConnectionFactoryLocator connectionFactoryLocator,
95 UsersConnectionRepository usersConnectionRepository,
100 new CanvasSignInController(
101 connectionFactoryLocator,
102 usersConnectionRepository,
103 new UserCookieSignInAdapter(),
104 env.getProperty("facebook.app.id"),
105 env.getProperty("facebook.app.secret"),
106 env.getProperty("facebook.app.canvas")
112 ## Step 4: Allow the URL Of Your Canvas-Page To Be Accessed Unauthenticated
114 Since [we have "secured" all of our pages](/develop-a-facebook-app-with-spring-social-part-05-refactor-the-redirect-logic "Read more about the refactoring, that ensures, that every request, that is made to our app, is authenticated") except of our sign-in-page `/signin*`, so that they can only be accessed by an authenticated user, we have to explicitly allow unauthenticated access to our new special sign-in-page.
116 To achieve that, we have to refine our [`UserCookieInterceptor`](/develop-a-facebook-app-with-spring-social-part-05-refactor-the-redirect-logic#redirect "Compare the changes to the unchanged method of our UserCookieInterceptor") as follows.
117 First add a pattern for all pages, that are allowed to be accessed unauthenticated:
120 private final static Pattern PATTERN = Pattern.compile("^/signin|canvas");
124 Then match the requests against this pattern, instead of the fixed string `/signin`:
127 if (PATTERN.matcher(request.getServletPath()).find())
132 ## Step 5: Enable Sign-Up Through Your Canvas-Page
134 Facebook always sends a `signed_request` to your app, if a user visits your app through the canvas-page.
135 But on the first visit of a user, the `signed_request` does not authenticate the user.
136 In this case, the only data that is presented to your page is the language and locale of the user and his or her age.
138 Because the data, that is needed to sign in the user, is missing, the `CanvasSignInController` will issue an explicit authentication-request to the Graph-API via a so called [Server-Side Log-In](https://developers.facebook.com/docs/games/gamesonfacebook/login#serversidelogin "Read more details about the process of a Server-Side Log-In on Facebook").
139 This process includes a redirect to the Login-Dialog of Facebook and then a second redirect back to your app.
140 It requires the specification of a full absolute URL to redirect back to.
142 Since we are configuring the canvas-login-in, we want, that new users are redirected to the canvas-page of our app.
143 Hence, you should use the Facebook-URL of your app: `https://apps.facebook.com/YOUR_NAMESPACE`.
144 This will result in a call to your canvas-page with a `signed_request`, that authenticates the new user, if the user accepts to share the requested data with your app.
146 Any other page of your app would work as well, but the result would be a call to the stand-alone version of your app (the version of your app that is called the "Website"-platform of your app by Facebook), meaning, that your app is not rendered inside of Facebook.
147 Also it requires one more call of your app to the Graph-API to actually sign-in the new user, because Facebook sends the `signed_request` only the canvas-page of your app.
149 To specify the URL I have introduced a new attribute `facebook.app.canvas` that is handed to the `CanvasSignInController`.
150 You can specifiy it, when starting your app:
153 mvn spring-boot:run \
154 -Dfacebook.app.id=YOUR_ID \
155 -Dfacebook.app.secret=YOUR_SECRET \
156 -Dfacebook.app.canvas=https://apps.facebook.com/YOUR_NAMESPACE
160 Be aware, that this process requires the automatic sign-up of new users, that we enabled in [part 3](/develop-a-facebook-app-with-spring-social-part-03-implementing-a-user-id-source#plumbing-UserIdSource "Jump back to part 3 of this series to reread, how we enabled the automatic sign-up") of this series.
161 Otherwise, the user would be redirected to the sign-up-page of your application, after he allowed your app to access the requested data.
162 Obviously, that would be very confusing for the user, so we really nead automati sign-up in this use-case!
166 In [the next part](/develop-a-facebook-app-with-spring-social-part-07-what-is-going-on-on-the-wire/ "Jump to the next part of this series and learn how to turn on debugging for the HTTP-communication between your app and the Graph-API") of this series, I will show you, how you can debug the calls, that Spring Social makes to the Graph-API, by turning on the debugging of the classes, that process the HTTP-requests and -responses, that your app is making.